yii2
ファイルのアップロード
サーチ…
どうやってするの
ファイルのアップロード
Yiiでファイルをアップロードするには、アップロードされた各ファイルをUploadedFile
オブジェクトとしてカプセル化する[[yii \ web \ UploadedFile]]の助けを借りて行うのが普通です。 [yii \ widgets \ ActiveForm]]とモデルを組み合わせることで、安全なファイルアップロードメカニズムを簡単に実装できます。
モデルの作成
プレーンテキスト入力で作業する場合と同様に、1つのファイルをアップロードするには、モデルクラスを作成し、モデルの属性を使用してアップロードされたファイルインスタンスを保持します。ファイルのアップロードを検証するための検証ルールも宣言する必要があります。例えば、
namespace app\models; use yii\base\Model; use yii\web\UploadedFile; class UploadForm extends Model { /** * @var UploadedFile */ public $imageFile; public function rules() { return [ [['imageFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'], ]; } public function upload() { if ($this->validate()) { $this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension); return true; } else { return false; } } }
上記のコードでは、 imageFile
属性はアップロードされたファイルインスタンスを保持するために使用されます。これは[[yii \ validators \ FileValidator]]を使用して、拡張子png
またはjpg
ファイルがアップロードされていることを確認するfile
検証規則に関連付けられていfile
。 upload()
メソッドは検証を実行し、アップロードされたファイルをサーバーに保存します。
file
バリデーターを使用すると、ファイルの拡張子、サイズ、MIMEタイプなどを確認できます。詳細については、コアバリデーターのセクションを参照してください。
ヒント:イメージをアップロードする場合は、代わりに
image
バリデータを使用することを検討してください。image
バリデーターは、[[yii \ validators \ ImageValidator]]を介して実装され、属性が有効なイメージを受け取ったかどうかを確認します。有効なイメージは、イメージ拡張機能を使用して保存または処理できます。
レンダリングファイルの入力
次に、ビューにファイル入力を作成します。
<?php use yii\widgets\ActiveForm; ?> <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?> <?= $form->field($model, 'imageFile')->fileInput() ?> <button>Submit</button> <?php ActiveForm::end() ?>
ファイルを適切にアップロードできるように、フォームにenctype
オプションを追加することを覚えておくことが重要です。 fileInput()
呼び出しは、ユーザーがアップロードするファイルを選択できるようにする<input type="file">
タグをレンダリングします。
ヒント:バージョン2.0.8以降、[[yii \ web \ widgets \ ActiveField :: fileInput | fileInput]]は、ファイル入力フィールドが使用されるときに自動的にフォームに
enctype
オプションを追加します。
結線
コントローラのアクションで、ファイルアップロードを実装するためのモデルとビューを結びつけるコードを書いてください:
namespace app\controllers; use Yii; use yii\web\Controller; use app\models\UploadForm; use yii\web\UploadedFile; class SiteController extends Controller { public function actionUpload() { $model = new UploadForm(); if (Yii::$app->request->isPost) { $model->imageFile = UploadedFile::getInstance($model, 'imageFile'); if ($model->upload()) { // file is uploaded successfully return; } } return $this->render('upload', ['model' => $model]); } }
上記のコードでは、フォームが送信されると、[[yii \ web \ UploadedFile :: getInstance()]]メソッドが呼び出され、アップロードされたファイルをUploadedFile
インスタンスとして表します。次に、モデルの検証を使用して、アップロードされたファイルが有効であることを確認し、ファイルをサーバーに保存します。
複数のファイルのアップロード
また、複数のファイルを一度にアップロードすることもできます。前の項で説明したコードをいくつか調整します。
まず、アップロードするファイルの最大数を制限するために、 file
検証規則にmaxFiles
オプションを追加して、モデルクラスを調整する必要があります。 maxFiles
を0
設定すると、同時にアップロードできるファイル数に制限がないことを意味します。同時にアップロードできるファイルの最大数は、PHPディレクティブのmax_file_uploads
(デフォルトは20 upload()
制限されていますmax_file_uploads
upload()
メソッドは、アップロードされたファイルを1つずつ保存するように更新する必要があります。
namespace app\models; use yii\base\Model; use yii\web\UploadedFile; class UploadForm extends Model { /** * @var UploadedFile[] */ public $imageFiles; public function rules() { return [ [['imageFiles'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg', 'maxFiles' => 4], ]; } public function upload() { if ($this->validate()) { foreach ($this->imageFiles as $file) { $file->saveAs('uploads/' . $file->baseName . '.' . $file->extension); } return true; } else { return false; } } }
ビューファイルでは、 fileInput()
呼び出しにmultiple
オプションを追加して、ファイルアップロードフィールドで複数のファイルを受信できるようにする必要があります。
<?php use yii\widgets\ActiveForm; ?> <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?> <?= $form->field($model, 'imageFiles[]')->fileInput(['multiple' => true, 'accept' => 'image/*']) ?> <button>Submit</button> <?php ActiveForm::end() ?>
そして最後にコントローラのアクションでは、あなたが呼び出す必要がありますUploadedFile::getInstances()
の代わりUploadedFile::getInstance()
の配列割り当てるためUploadedFile
にインスタンスUploadForm::imageFiles
。
namespace app\controllers; use Yii; use yii\web\Controller; use app\models\UploadForm; use yii\web\UploadedFile; class SiteController extends Controller { public function actionUpload() { $model = new UploadForm(); if (Yii::$app->request->isPost) { $model->imageFiles = UploadedFile::getInstances($model, 'imageFiles'); if ($model->upload()) { // file is uploaded successfully return; } } return $this->render('upload', ['model' => $model]); } }