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. Walidatorimagejest 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ę
enctypedo 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]);
}
}