yii2
Przesyłanie plików
Szukaj…
Jak to zrobić
Przesyłanie plików
Przesyłanie plików w Yii odbywa się zwykle za pomocą [[yii \ web \ UploadedFile]], który zawiera każdy przesłany plik jako obiekt UploadedFile
. W połączeniu z [[yii \ widgets \ ActiveForm]] i modelami możesz łatwo wdrożyć bezpieczny mechanizm przesyłania plików.
Tworzenie modeli
Podobnie jak praca z wprowadzaniem zwykłego tekstu, aby przesłać pojedynczy plik, należy utworzyć klasę modelu i użyć atrybutu modelu, aby zachować przesłaną instancję pliku. Należy również zadeklarować regułę sprawdzania poprawności, aby sprawdzić poprawność przesłanego pliku. Na przykład,
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; } } }
W powyższym kodzie atrybut imageFile
służy do zachowania przesłanej instancji pliku. Jest on powiązany z regułą sprawdzania poprawności file
która korzysta z [[yii \ validators \ FileValidator]], aby zapewnić przesłanie pliku o nazwie rozszerzenia png
lub jpg
. Metoda upload()
przeprowadzi sprawdzenie poprawności i zapisze przesłany plik na serwerze.
Walidator file
umożliwia sprawdzenie rozszerzeń plików, rozmiaru, typu MIME itp. Więcej informacji znajduje się w sekcji Core Validators.
Wskazówka: jeśli przesyłasz obraz, możesz zamiast tego rozważyć użycie walidatora
image
. Walidatorimage
jest implementowany za pośrednictwem [[yii \ validators \ ImageValidator]], który sprawdza, czy atrybut otrzymał prawidłowy obraz, który można następnie zapisać lub przetworzyć za pomocą rozszerzenia Imagine .
Renderowanie pliku wejściowego
Następnie utwórz plik wejściowy w widoku:
<?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() ?>
Ważne jest, aby pamiętać, że dodajesz opcję enctype
do formularza, aby plik mógł zostać poprawnie przesłany. fileInput()
spowoduje wyświetlenie <input type="file">
który pozwoli użytkownikom wybrać plik do przesłania.
Wskazówka: od wersji 2.0.8 [[yii \ web \ widgets \ ActiveField :: fileInput | fileInput]] dodaje opcję
enctype
do formularza automatycznie, gdy używane jest pole wejściowe pliku.
Okablowanie
Teraz w akcji kontrolera napisz kod, aby połączyć model i widok, aby zaimplementować przesyłanie plików:
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]); } }
W powyższym kodzie, gdy formularz jest przesyłany, wywoływana jest metoda [[yii \ web \ UploadedFile :: getInstance ()]] w celu reprezentowania przesłanego pliku jako instancji UploadedFile
. Następnie polegamy na sprawdzeniu poprawności modelu, aby upewnić się, że przesłany plik jest prawidłowy i zapisać plik na serwerze.
Przesyłanie wielu plików
Możesz także przesłać wiele plików jednocześnie, z pewnymi modyfikacjami kodu wymienionego w poprzednich podsekcjach.
Najpierw należy dostosować klasę modelu, dodając opcję maxFiles
do reguły sprawdzania poprawności file
aby ograniczyć maksymalną liczbę plików, które można przesłać. Ustawienie wartości maxFiles
na 0
oznacza, że nie ma ograniczenia liczby plików, które można jednocześnie przesłać. Maksymalna liczba plików, które mogą być przesyłane jednocześnie, jest również ograniczona przez dyrektywę PHP max_file_uploads
, która domyślnie max_file_uploads
20. Należy również zaktualizować metodę upload()
aby zapisywać przesłane pliki jeden po drugim.
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; } } }
W pliku widoku należy dodać opcję multiple
do fileInput()
aby pole wysyłania pliku mogło odbierać wiele plików:
<?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() ?>
I wreszcie w akcji kontrolera powinieneś wywołać UploadedFile::getInstances()
zamiast UploadedFile::getInstance()
aby przypisać tablicę instancji UploadedFile
do 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]); } }