Uploading files

The common task when data is sent from view to controller is uploading files. Also, in this case, Yii2 provides a convenient helper to handle this task: yiiwebUploadedFile. This class has two important methods: getInstance() (in plural form getInstances()) and saveAs().

The first method, getInstance(), allows us to get the file from the form's input field, while the second method, saveAs(), as its name implies, allows us to save file input field content to the server filesystem.

Before we start with the example, it is important to create a folder that will contain the uploaded files. The best place to create this folder is at the root directory of the application. So create a folder named uploadedfiles under the basic/ folder.

Note

Make sure that this folder is writable.

Next, to centralize configuration, define an alias for this new folder, so that we can change this path from app configuration. Enter in basic/config/web.php and append the aliases property, if it does not exist, to the $config array with these lines:

'aliases' =>
[
        '@uploadedfilesdir' => '@app/uploadedfiles'
],

Note

@app is a system aliases that defines the application's root directory.

Example – uploading an image of a room

In this example, we will see how to upload an image of a room.

We need to make changes in model, view, and controller. Let's start with model.

In model, we need to add a new property, named fileImage, with its specific rule.

This is the final version of Model:

<?php
namespace appmodels;
use Yii;
use yiiaseModel;
class Room extends Model
{
    public $floor; 
    public $room_number;
    public $has_conditioner;
    public $has_tv;
    public $has_phone;
    public $available_from;
    public $price_per_day;
    public $description;
    
    public $fileImage;
    
    public function attributeLabels()
    {
        return [
            'floor' => 'Floor',
            'room_number' => 'Room number',
            'has_conditioner' => 'Conditioner available',
            'has_tv' => 'TV available',
            'has_phone' => 'Phone available',
            'available_from' => 'Available from',
            'price_per_day' => 'Price (Eur/day)',
            'description' => 'Description',
            'fileImage' => 'Image'
        ];
    }
    
    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            ['floor', 'integer', 'min' => 0],
            ['room_number', 'integer', 'min' => 0],
            [['has_conditioner', 'has_tv', 'has_phone'], 'integer', 'min' => 0, 'max' => 1],
            ['available_from', 'date', 'format' => 'php:Y-m-d'],
            ['price_per_day', 'number', 'min' => 0],
            ['description', 'string', 'max' => 500],
            
            ['fileImage', 'file']
        ];
    } 
}

In rules, for the fileImage field, we can add many types of validation; for example, check if required, check mime type (.gif, .jpeg, and .png).

Next, we will use the static method getInstance() of the UploadedFile class in controller, to get the file from the input file field and then use saveAs to save in the specific folder. This is the final version of RoomsController:

<?php

namespace appcontrollers;

use Yii;
use yiiwebController;
use appmodelsRoom;

class RoomsController extends Controller
{
    public function actionCreate()
    {
        $model = new Room();
        $modelCanSave = false;

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {

            $model->fileImage = UploadedFile::getInstance($model, 'fileImage');

            if ($model->fileImage) { 
                $model->fileImage->saveAs(Yii::getAlias('@uploadedfilesdir/' . $model->fileImage->baseName . '.' . $model->fileImage->extension)));
            } 
            
            $modelCanSave = true;
        }
        
        return $this->render('create', [
            'model' => $model,
            'modelSaved' => $modelCanSave
        ]);
    }
}

UploadedFile::getInstance gets the file from the $_FILES array to fill the fileImage property of Model with its data.

The last thing to do is to update the create view content, by appending the fileInput field. This is the final version:

<?php
use yiihelpersHtml;
use yiiwidgetsActiveForm;
use yiihelpersUrl;
use yiihelpersArrayHelper;
?>

<?php if($modelCanSave) { ?>
<div class="alert alert-success">
    Model ready to be saved!
    <br /><br />
    These are values: <br />
    Floor: <?php echo $model->floor; ?> <br />
    Room Number: <?php echo $model->room_number; ?> <br />
    Has conditioner: <?php echo Yii::$app->formatter->asBoolean($model->has_conditioner); ?> <br />
    Has TV: <?php echo Yii::$app->formatter->asBoolean($model->has_tv); ?> <br />
    Has phone: <?php echo Yii::$app->formatter->asBoolean($model->has_phone); ?> <br />
    Available from (mm/dd/yyyy): <?php echo Yii::$app->formatter->asDate($model->available_from,'php:m/d/Y'); ?> <br />
    Price per day: <?php echo Yii::$app->formatter->asCurrency($model->price_per_day,'EUR'); ?> <br />
    Image:
    <?php if(isset($model->fileImage)) { ?>
        <img src="<?php echo Url::to('@uploadedfilesdir/'.$model->fileImage->name) ?>" />
    <?php } ?>
</div>
<?php } ?>

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>  
<div class="row">
    <div class="col-lg-12">
        <h1>Room form</h1>
        <?= $form->field($model, 'floor')->textInput() ?>
        <?= $form->field($model, 'room_number')->textInput() ?>
        <?= $form->field($model, 'has_conditioner')->checkbox() ?>
        <?= $form->field($model, 'has_tv')->checkbox() ?>
        <?= $form->field($model, 'has_phone')->checkbox() ?>
        <?= $form->field($model, 'available_from')->textInput() ?>
        <?= $form->field($model, 'price_per_day')->textInput() ?>
        <?= $form->field($model, 'description')->textarea() ?>
        
        
        <?= $form->field($model, 'fileImage')->fileInput() ?>
   </div>
</div>
<div class="form-group">
    <?= Html::submitButton('Create' , ['class' => 'btn btn-success']) ?>
</div>
<?php ActiveForm::end(); ?>

Take care of the last row of this example, ActiveForm::end() that closes the body of the $form widget defined at the top of the file using the ActiveForm::begin() method.

Note

In this example, the ActiveForm widget has been created by filling the enctype property of the configuration array with the multipart/form-data value, which allows us to send the binary data other than the form text parameters. However, this does not deal with Yii or PHP, because this is an HTML requirement for notifying the browser how to send files to the server.

In this view, if the model has been validated and the fileImage property is filled, the corresponding image will be displayed.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.70.132