ZendFramework-ファイルのアップロード
ファイルのアップロードは、フォームプログラミングの主要な概念の1つです。Zend Frameworkは、ファイルをアップロードするために必要なすべてのアイテムを提供します。zend-form そしてその zend-inputfilter 成分。
FileInputクラス
zend-inputfilterコンポーネントは、htmlファイル入力要素を処理するためのZend \ InputFilter \ FileInputクラスを提供します– <input type = 'file' />。ザ・FileInputいくつかの例外を除いて、他の入力フィルターと同様です。それらは次のとおりです-
PHPはアップロードされたファイルの詳細をに保存するため $_FILES グローバル配列の場合、FileInputは、アップロードされたファイル情報を$ _FILESのみを介して収集します。
FileInputクラスがデータを処理する前に、検証を行う必要があります。これは、他の入力フィルターとは逆の動作です。
Zend \ Validator \ File \ UploadFileは、使用されるデフォルトのバリデーターです。ザ・UploadFile ファイル入力の詳細を検証します。
フォームにファイルアップロードタイプを追加するには、入力タイプを使用する必要があります File。部分コードは次のとおりです-
$form->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array('label' => 'Picture',),
));
ファイルのアップロードで使用される別のクラスは、Zend \ Filter \ File \ RenameUploadです。ザ・RenameUploadアップロードされたファイルを目的の場所に移動するために使用されます。ファイルフィルターを使用する部分クラスは次のとおりです。
$file = new FileInput('imagepath');
$file->getValidatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach(
new RenameUpload([
'target' => './public/tmpuploads/file',
'randomize' => true,
'use_upload_extension' => true
]));
$inputFilter->add($file);
ここでは、のオプション RenameUpload 次のとおりです-
target −アップロードされたファイルの宛先パス。
randomize −アップロードされたファイルの重複を防ぐために、ランダムな文字列を追加します。
use_upload_extension −アップロードしたファイルの拡張子をターゲットに追加します。
ファイルのアップロード–実例
チュートリアルモジュールを変更して、画像のアップロード機能を含めましょう。
データベーステーブルを変更する
追加しましょう imagepath 次のSQLコマンドを実行してbookテーブルに列を追加します-
ALTER TABLE `book` ADD `imagepath` VARCHAR(255) NOT NULL AFTER 'imagepath';
BookForm.phpを更新する
ファイル入力要素を追加して、本のフォームに画像をアップロードします– myapp / module / Tutorial / src / Model /BookForm.php。
次のコードをに含めます __constructmethod BookFormクラスの。
$this->add(array(
'name' => 'imagepath',
'type' => 'File',
'options' => array ('label' => 'Picture',),
));
Book.phpを更新する
Bookクラスで次の変更を行います– myapp / module / Tutorial / src / Model /Book.php。
新しいプロパティを追加します imagepath 写真のために。
public $imagepath;
を更新します getInputFilter 以下に示す方法-
追加します FileInput ファイル入力要素のフィルター。
をセットする UploadFile ファイル入力要素を検証するための検証。
を構成します RenameUpload アップロードしたファイルを適切な宛先に移動します。
部分的なコードリストは次のとおりです-
$file = new FileInput('imagepath');
$file->getValidatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach(
new RenameUpload([
'target' => './public/tmpuploads/file',
'randomize' => true, 'use_upload_extension' => true
]));
$inputFilter->add($file);
を更新します exchangeArray 含める方法 imagepathプロパティ。イメージパスは、フォームまたはデータベースから取得できます。イメージパスがフォームからのものである場合、フォーマットは次の仕様の配列になります-
array(1) {
["imagepath"] => array(5) {
["name"] => string "myimage.png"
["type"] => string "image/png"
["tmp_name"] => string
"public/tmpuploads/file_<random_string>.<image_ext>"
["error"] => int <error_number>
["size"] => int <size>
}
}
イメージパスがデータベースからのものである場合、それは単純な文字列になります。イメージパスを解析するための部分的なコードリストは次のとおりです。
if(!empty($data['imagepath'])) {
if(is_array($data['imagepath'])) {
$this->imagepath = str_replace("./public", "", $data['imagepath']['tmp_name']);
} else {
$this->imagepath = $data['imagepath'];
}
} else {
$data['imagepath'] = null;
}
の完全なリスト Book モデルは次のとおりです-
<?php
namespace Tutorial\Model;
use Zend\InputFilter\InputFilterInterface;
use Zend\InputFilter\InputFilterAwareInterface;
use Zend\Filter\File\RenameUpload;
use Zend\Validator\File\UploadFile;
use Zend\InputFilter\FileInput;
use Zend\InputFilter\InputFilter;
class Book implements InputFilterAwareInterface {
public $id;
public $author;
public $title;
public $imagepath;
protected $inputFilter;
public function setInputFilter(InputFilterInterface $inputFilter) {
throw new \Exception("Not used");
}
public function getInputFilter() {
if (!$this->inputFilter) {
$inputFilter = new InputFilter();
$inputFilter->add(array(
'name' => 'id',
'required' => true,
'filters' => array(
array('name' => 'Int'),
),
));
$inputFilter->add(array(
'name' => 'author',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
));
$inputFilter->add(array(
'name' => 'title',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 100,
),
),
),
));
$file = new FileInput('imagepath');
$file->getValidatorChain()->attach(new UploadFile());
$file->getFilterChain()->attach(
new RenameUpload([
'target' => './public/tmpuploads/file',
'randomize' => true,
'use_upload_extension' => true
]));
$inputFilter->add($file);
$this->inputFilter = $inputFilter;
}
return $this->inputFilter;
}
public function exchangeArray($data) {
$this->id = (!empty($data['id'])) ? $data['id'] : null;
$this->author = (!empty($data['author'])) ? $data['author'] : null;
$this->title = (!empty($data['title'])) ? $data['title'] : null;
if(!empty($data['imagepath'])) {
if(is_array($data['imagepath'])) {
$this->imagepath = str_replace("./public", "",
$data['imagepath']['tmp_name']);
} else {
$this->imagepath = $data['imagepath'];
}
} else {
$data['imagepath'] = null;
}
}
}
BookTable.phpを更新します
更新しました BookForm そしてその Book model。今、私たちは更新しますBookTable を変更します saveBook方法。これは、データ配列にimagepathエントリを含めるのに十分です。$data。
部分的なコードリストは次のとおりです-
$data = array('author' => $book->author, 'title' => $book->title,
'imagepath' => $book->imagepath
);
の完全なコードリスト BookTable クラスは次のとおりです-
<?php
namespace Tutorial\Model;
use Zend\Db\TableGateway\TableGatewayInterface;
class BookTable {
protected $tableGateway;
public function __construct(TableGatewayInterface $tableGateway) {
$this->tableGateway = $tableGateway;
}
public function fetchAll() {
$resultSet = $this->tableGateway->select();
return $resultSet;
}
public function getBook($id) {
$id = (int) $id;
$rowset = $this->tableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
public function saveBook(Book $book) {
$data = array (
'author' => $book->author,
'title' => $book->title,
'imagepath' => $book->imagepath
);
$id = (int) $book->id;
if ($id == 0) {
$this->tableGateway->insert($data);
} else {
if ($this->getBook($id)) {
$this->tableGateway->update($data, array('id' => $id));
} else {
throw new \Exception('Book id does not exist');
}
}
}
}
Update addAction in the TutorialController.php:ファイルのアップロード情報は、 $_FILES グローバル配列であり、を使用してアクセスできます Request's getFiles()方法。したがって、以下に示すように、投稿されたデータとファイルのアップロード情報の両方をマージします。
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
の完全なリスト addAction() 方法は次のとおりです-
public function addAction() {
$form = new BookForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$book = new Book();
$form->setInputFilter($book->getInputFilter());
$post = array_merge_recursive(
$request->getPost()->toArray(),
$request->getFiles()->toArray()
);
$form->setData($post);
if ($form->isValid()) {
$book->exchangeArray($form->getData());
$this->bookTable->saveBook($book);
// Redirect to list of Tutorial
return $this->redirect()->toRoute('tutorial');
}
}
return array('form' => $form);
}
add.phtmlのビューを更新
最後に、「add.phtml」を変更し、以下に示すようにimagepathファイルの入力要素を含めます-
echo $this->formRow($form->get('imagepath'))."<br>";
完全なリストは次のとおりです-
<?php
$title = 'Add new Book';
$this->headTitle($title);
?>
<h1><?php echo $this->escapeHtml($title); ?></h1>
<?php
if(!empty($form)) {
$form->setAttribute('action', $this->url('tutorial', array('action' => 'add')));
$form->prepare();
echo $this->form()->openTag($form);
echo $this->formHidden($form->get('id'));
echo $this->formRow($form->get('author'))."<br>";
echo $this->formRow($form->get('title'))."<br>";
echo $this->formRow($form->get('imagepath'))."<br>";
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();
}
アプリケーションを実行する
最後に、でアプリケーションを実行します http://localhost:8080/tutorial/add 新しいレコードを追加します。
結果は次のスクリーンショットのようになります-
Form Page
Index Page