如何使用Yii2编程:上传文件

最终产品图片
您将要创造的

如果您问“ Yii是什么?” 查阅我之前的教程: Yii Framework简介 ,它回顾了Yii的优点,并概述了2014年10月发布的Yii 2.0的新功能。

在本《 如何使用Yii2编程》系列中 ,我指导读者使用PHP的Yii2框架。 在本教程中,我将指导您了解在Yii2中上传文件和图像的基础知识。

对于这些示例,我们将继续想象我们正在构建一个用于发布简单状态更新的框架,例如我们自己的微型Twitter。 上图显示了上传我拍摄的泰姬陵照片时写的简短更新。

提醒一下,我确实参与了下面的评论主题。 如果您有不同的方法,其他想法或想为将来的教程提供建议,我特别感兴趣。 如果您有任何问题或建议,请在下面发布。 您也可以直接通过Twitter @reifman与联系

文件上传插件

Yii2图片上传-Kartik文件输入小部件演示示例

Yii2有两个似乎最强大的文件上传插件:

  1. Kartik Visweswaran的FileInput小部件 (如上所示)
  2. 2Amigos BlueImp文件上载器BlueImp JQuery 文件上载器的包装

对于本教程,我决定继续使用Kartik的插件。 我发现它比2Amigos插件更易于使用和文档记录。 但是,BlueImp File Uploader具有一些您可能想要探索的有趣的用户体验功能(如下所示):

Yii2图片上传-2Amigos和BlueImp文件上传示例

使用FileInput插件

让我们开始安装和使用文件上传器,并将其集成到类似Twitter的状态创建小程序中。 同样,我们将使用Yii2 Hello应用程序树,您可以通过旁边或下方的GitHub按钮链接下载该树。

安装插件

首先,我们可以使用composer将kartik-v/yii2-widget-fileinput到我们的应用程序中:

$ composer require kartik-v/yii2-widget-fileinput "*"
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Updating kartik-v/yii2-widget-fileinput (dev-master 36f9f49 => v1.0.4)
    Checking out 36f9f493c2d814529f2a195422a8af2e020fc80c

Writing lock file
Generating autoload files

扩展状态表

接下来,我们需要为要上传到“状态”表中的文件添加字段。 在此示例中,我们将允许用户上传图像以及其状态更新。

我们将添加的字段用于上传文件的原始文件名以及将存储在我们服务器上以供显示的唯一文件名:

  • image_src_filename
  • image_web_filename

创建一个新的迁移,以将以下字段添加到“状态”表中:

$ ./yii migrate/create extend_status_table_for_image
Yii Migration Tool (based on Yii v2.0.6)

Create new migration '/Users/Jeff/Sites/hello/migrations/m160316_201654_extend_status_table_for_image.php'? (yes|no) [no]:yes
New migration created successfully.

这是将两个字段添加为字符串的定制迁移:

<?php

use yii\db\Schema;
use yii\db\Migration;

class m160316_201654_extend_status_table_for_image extends Migration
{
    public function up()
    {
      $tableOptions = null;
      if ($this->db->driverName === 'mysql') {
          $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
      }
      $this->addColumn('{{%status}}','image_src_filename',Schema::TYPE_STRING.' NOT NULL');
      $this->addColumn('{{%status}}','image_web_filename',Schema::TYPE_STRING.' NOT NULL');
    }

    public function down()
    {
        $this->dropColumn('{{%status}}','image_src_filename');
        $this->dropColumn('{{%status}}','image_web_filename');
        return false;
    }

}

然后,运行迁移:

$ ./yii migrate/up
Yii Migration Tool (based on Yii v2.0.6)

Total 1 new migration to be applied:
    m160316_201654_extend_status_table_for_image

Apply the above migration? (yes|no) [no]:yes
*** applying m160316_201654_extend_status_table_for_image
    > add column image_src_filename string NOT NULL to table {{%status}} ... done (time: 0.044s)
    > add column image_web_filename string NOT NULL to table {{%status}} ... done (time: 0.011s)
*** applied m160316_201654_extend_status_table_for_image (time: 0.071s)


Migrated up successfully.

由于Yii2是使用模型视图控制器(MVC)架构构建的,因此我们需要为文件上传器实现其他三个编码区域:

  1. 状态模型
  2. 状态视图和表格
  3. 状态控制器

增强模型功能

现在,我们将对/models/Status.php文件进行更改。 首先,我们需要提供新图像字段的属性和验证规则,以及小部件将用来上传文件的临时$image变量。

下面,我们为两个新的$image_xxx_filename变量添加注释,并创建一个名为$image的公共临时变量:

/**
 * This is the model class for table "status".
 *
 * @property integer $id
 * @property string $message
 * @property integer $permissions
 * @property string $image_src_filename
 * @property string $image_web_filename
 * @property integer $created_at
 * @property integer $updated_at
 * @property integer $created_by 
 * 
 * @property User $createdBy
 */
class Status extends \yii\db\ActiveRecord
{
      const PERMISSIONS_PRIVATE = 10;
      const PERMISSIONS_PUBLIC = 20;  
      public $image;

接下来,我们将为图像添加验证规则,例如文件类型和最大大小:

public function rules()
    {
        return [        
            [['message'], 'required'],
            [['message'], 'string'],
            [['permissions', 'created_at', 'updated_at','created_by'], 'integer'],
            [['image'], 'safe'],
            [['image'], 'file', 'extensions'=>'jpg, gif, png'],
            [['image'], 'file', 'maxSize'=>'100000'],
             [['image_src_filename', 'image_web_filename'], 'string', 'max' => 255],        ];
    }

以及视图的新属性标签:

public function attributeLabels()
    {
        return [
          'id' => Yii::t('app', 'ID'),
          'message' => Yii::t('app', 'Message'),
          'permissions' => Yii::t('app', 'Permissions'),
          'image_src_filename' => Yii::t('app', 'Filename'),
          'image_web_filename' => Yii::t('app', 'Pathname'),          
          'created_by' => Yii::t('app', 'Created By'),
          'created_at' => Yii::t('app', 'Created At'),
          'updated_at' => Yii::t('app', 'Updated At'),        ];
    }

现在我们可以继续查看ActiveModel表单中的View更改。

添加我们的视图和表单功能

将图像上传集成到状态创建表单
Yii2图片上传-使用我们的新文件输入功能来创建状态

要启用图像上传到状态更新的表单集成(如上所示),我们需要对/views/status/_form.php文件进行更改。

首先,我们在顶部附近添加kartik\file\FileInput小部件,并将表单更新为多部分,从而支持发布文件:

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use app\assets\StatusAsset;
use kartik\file\FileInput;

StatusAsset::register($this);

/* @var $this yii\web\View */
/* @var $model app\models\Status */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="status-form">
  <?php 
      $form = ActiveForm::begin([
          'options'=>['enctype'=>'multipart/form-data']]); // important         
           ?>

然后,在“权限”字段和“提交”按钮之间,添加FileInput小部件:

<?=
        $form->field($model, 'permissions')->dropDownList($model->getPermissions(), 
                 ['prompt'=>Yii::t('app','- Choose Your Permissions -')]) ?>
               </div>
    </div>
    <div class="row">
      <?= $form->field($model, 'image')->widget(FileInput::classname(), [
              'options' => ['accept' => 'image/*'],
               'pluginOptions'=>['allowedFileExtensions'=>['jpg','gif','png'],'showUpload' => false,],
          ]);   ?>
  </div>
    <div class="row">
                 
    <div class="form-group">
 <?= Html::submitButton($model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'), ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
     </div>
   </div>

pluginOptions行中,我们将文件类型限制为常见的图像格式,例如jpg。

完成后,它将看起来像这样,等待用户添加图像:

Yii2图像上传-创建状态页面并添加了文件上传
显示影像

我还将添加代码以显示上载的图像以供以后使用(在完成对控制器的支持之后)。

首先,我将其添加到状态视图页面( /views/status/view.php ),这是非常基础的。 但是,我将在项目详细信息下方显示图像:

<?= DetailView::widget([
        'model' => $model,
        'attributes' => [
            'id',
            'createdBy.email',
            'message:ntext',
            'permissions',
            'image_web_filename',
            'image_src_filename',
            'created_at',
            'updated_at',
        ],
    ]) ?>
    
    <?php
       if ($model->image_web_filename!='') {
         echo '<br /><p><img src="'.Yii::$app->homeUrl. '/uploads/status/'.$model->image_web_filename.'"></p>';
       }    
    ?>

它看起来像这样:

Yii2图像上传-增强的状态视图,下面有图像

我们还将在状态索引页面( /views/status/index.php )中添加一个小的缩略图视图。 我向Yii2的GridView小部件添加了一个自定义列属性:

<?= GridView::widget([
           'dataProvider' => $dataProvider,
           'filterModel' => $searchModel,
           'columns' => [
               ['class' => 'yii\grid\SerialColumn'],
               'id',
               'message:ntext',
               'permissions',
               'created_at',
               [
                     'attribute' => 'Image',
                     'format' => 'raw',
                     'value' => function ($model) {   
                        if ($model->image_web_filename!='')
                          return '<img src="'.Yii::$app->homeUrl. '/uploads/status/'.$model->image_web_filename.'" width="50px" height="auto">'; else return 'no image';
                     },
                   ],
           	      ['class' => 'yii\grid\ActionColumn',
   				      'template'=>'{view} {update} {delete}',
   					    'buttons'=>[
                   'view' => function ($url, $model) {     
                     return Html::a('<span class="glyphicon glyphicon-eye-open"></span>', 'status/'.$model->slug, ['title' => Yii::t('yii', 'View'),]);	
   						      }
   							],
   			      ],
           ],
       ]); ?>

最终,它将如下所示:

Yii2图片上传-带有上传图片缩略图的增强状态索引

建立控制器支持

为了使以上所有可能成为可能,我们需要完成控制器集成。

/controllers/StatusController.php的顶部,我们必须包含yii\web\UploadedFile

<?php
namespace app\controllers;
use Yii;
use app\models\Status;
use app\models\StatusSearch;
use app\models\User;
use app\components\AccessRule;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\web\UploadedFile;

然后,我们必须更新actionCreate函数:

public function actionCreate()
    {
        $model = new Status();

        if ($model->load(Yii::$app->request->post())) {
          $image = UploadedFile::getInstance($model, 'image');
           if (!is_null($image)) {
             $model->image_src_filename = $image->name;
             $ext = end((explode(".", $image->name)));
              // generate a unique file name to prevent duplicate filenames
              $model->image_web_filename = Yii::$app->security->generateRandomString().".{$ext}";
              // the path to save file, you can set an uploadPath
              // in Yii::$app->params (as used in example below)                       
              Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/web/uploads/status/';
              $path = Yii::$app->params['uploadPath'] . $model->image_web_filename;
               $image->saveAs($path);
            }
            if ($model->save()) {             
                return $this->redirect(['view', 'id' => $model->id]);             
            }  else {
                var_dump ($model->getErrors()); die();
             }
              }
              return $this->render('create', [
                  'model' => $model,
              ]);     
    }

本质上,这将执行以下操作:

  1. 我们从上传文件的表单信息( image_src_filename )中捕获原始文件名。
  2. 我们为服务器生成一个唯一的文件名( image_web_filename )。
  3. 我们将文件保存到我们的上传目录( /web/uploads/status/ )。
  4. 我们保存模型。
  5. 我们重定向到增强型视图页面。

您可以在上面的图像中看到最终的结果,其中包括泰姬陵的照片。

Kartik的File Input Widget还提供了更高级的配置,这些配置他都很好地记录在案,例如拖放:

Yii2图像上传-带有拖放功能的增强的文件输入小部件选项

在以下页面上查看更多这些内容:

下一步是什么?

希望这对您在Yii2应用程序中上传文件的基础有所帮助。 如果您希望看到这种功能的另一个类似的演练,请查看使用PHP构建您的启动:用户设置,个人资料图片和联系方式 。 该教程使用选项卡,更新用户配置文件和缩放图像,与本教程提供的集成稍有不同。

Yii2 File Uploader Meeting Planner用户个人资料图片上传

在继续研究框架的不同方面时,请观看“ 如何使用Yii2编程”系列中即将发布的教程。 您可能还需要查看“ 使用PHP构建您的启动”系列 ,该系列在构建真实应用程序时使用了Yii2的高级模板。

如果您想知道下一个Yii2教程何时到达, 在Twitter上关注我@reifman查看我的讲师页面 。 发布后,我的讲师页面将包含本系列中的所有文章。

相关链接

这是我用来研究和编写本教程的各种链接:

翻译自: https://code.tutsplus.com/tutorials/how-to-program-with-yii2-uploading-files--cms-23511

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值