如何在表单中创建文件输入,上传文件并在数据库中写入 link

How create file input at form, which upload file and write link in database

我正在尝试通过编写自己的 cms 来学习 Yii2。

我想实现商店物品的附件照片。我不知道这样做的正确方法,但我认为应该如此 -

  1. 保存时,将在多个文件输入中选择的文件上传到服务器。
  2. 每张照片得到url
  3. 按模板在数据库单元格中写入链接

    <div class="itemImgs">
        <img class="0" src="{link}"> <!-- first -->
        <img class="1" src="{link}"> <!-- second -->
        <img class="..." src="{link}"> <!-- ... -->
    </div>
    

请帮助我理解我必须在模型 and\or 控制器中编写的内容,如果它是正确的方式。否则,请告诉我应该怎么做。

谢谢。

UPD

控制器中的动作:

  public function actionCreate() {
    $model = new ShopItems();
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
      return $this->redirect(['view', 'id' => $model->id]);
    } else {
      return $this->render('create', [
        'model' => $model,
        'category' => ShopCategories::find()->all()
      ]);
    }
  }

型号包含以下功能:

  public function behaviors() {
    return [
      TimestampBehavior::className(),
    ];
  }

  /** @inheritdoc */
  public static function tableName() {return 'shop_items';}

  /** @inheritdoc */
  public function rules() {
    return [
      [['category_id', 'title', 'desc', 'price', ], 'required'],
      [['category_id', 'price', 'in_stock', 'discount',], 'integer'],
      [['desc', 'options',], 'string'],
      [['photos',], 'file', 'maxFiles' => 10],
      [['title'], 'string', 'max' => 100]
    ];
  }

  /** @inheritdoc */
  public function attributeLabels() {
    return [
      'id' => 'ID',
      'category_id' => 'Категория',
      'title' => 'Название',
      'desc' => 'Описание',
      'price' => 'Цена',
      'discount' => 'Скидка %',
      'in_stock' => 'На складе',
      'photos' => 'Фото',
      'options' => 'Опции',
      'created_at' => 'Дата добавления',
      'updated_at' => 'Последнее редактирование',
    ];
  }

和视图 _form.php:

  <?php $form = ActiveForm::begin(); ?>

    <div class="col-lg-6">

      <?= $form->field($model, 'title')->textInput(['maxlength' => 100]) ?>

      <?= $form->field($model, 'desc')->textarea(['class' => 'ckeditor',]);  ?>

    </div>
    <div class="col-lg-6">

      <?= $form->field($model, 'category_id')->dropDownList(
        ArrayHelper::map($category, 'category_id', 'category_name')
      ) ?>

      <?= $form->field($model, 'price')->textInput() ?>

      <?= $form->field($model, 'discount')->textInput() ?>

      <?= $form->field($model, 'in_stock')->textInput() ?>

      <?= $form->field($model, 'photos[]')->fileInput(['multiple' => true]) ?>

      <?= $form->field($model, 'options')->textInput() ?>

    </div>

    <div class="clearfix"></div>

    <div class="col-xs-12">
      <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Добавить' : 'Принять изменения', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
      </div>
    </div>

  <?php ActiveForm::end(); ?>

查看文档 - http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html#uploading-multiple-files

controller中:

if ($model->file && $model->validate()) {
                foreach ($model->file as $file) {
                    $file->saveAs('uploads/' . $file->baseName . '.' . $file->extension);
                }
            }

输入模型Photo:

if ($model->file && $model->validate()) {
                foreach ($model->file as $file) {
                    $path = 'uploads/' . $file->baseName . '.' . $file->extension;
                    $file->saveAs($path);
                    $photo = new Photo();
                    $photo->path = $path; 
                    $photo->save();
                }
            }

像这样的照片table:

CREATE TABLE `photo` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `path` VARCHAR(255) NOT NULL ,
    `status` TINYINT(1) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
)
ENGINE=InnoDB;

获取照片使用:

$photos = Photo::find()->all();

在视图中:

<div class="itemImgs">
    <?php foreach ($photos as $k=>$photo) ?>
     <img class="<?= $k ?>" src="<?= $photo->path ?>"/><br/>
    <?php } ?>
</div>

编辑 在控制器中设置

 if ($model->load(Yii::$app->request->post()) && $model->validate()) {
     $files = UploadedFile::getInstances($model, 'file');
     $photosArr = [];
     foreach ($files as $file) {
        $path = 'uploads/' . $file->baseName . '.' . $file->extension;
        $file->saveAs($path);
        $photosArr[] = $path;
     }

     $model->photos = Json::encode($photosArr);// better put json in afterSave
     $model->save(false);// because validate() run before

      return $this->redirect(['view', 'id' => $model->id]);
    }

在字段 photos 中,您会得到 JSON 以及上传照片的路径。在视图中:

$arr = Json::decode($model->photos); // better put in afterFind()
foreach ($arr as $path) {
  echo '<img src="'.$path.'">';
}