是否可以在 yii2 中从 ActiveRecord 继承的模型中上传文件?
is it possible to upload a file in a model that inherits from ActiveRecord in yii2?
我用 Gii 从数据库 table 中生成了一个模型 yii2.this 模型继承自 ActiveRecord 。然后我从这个 model.now 创建了一个表单我想用这个表单上传一个文件。
是否可以上传具有相同模型(继承自 ActiveRecord)的文件?
如果是,怎么办?
如果没有,我该怎么办?
是的,这是可能的,但使用单独的表格是更好的做法。它在文章 Uploading files
的官方文档中有详细描述
创建单独的表单:
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;
}
}
}
渲染文件输入:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end() ?>
自定义控制器以处理文件上传:
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]);
}
}
本文还介绍了上传多个文件。
另见 this related question。
如果要与ActiveRecord
一起使用,并将文件路径保存为模型属性,可以在表单的upload()
方法中添加模型创建和保存。使用表单的另一个很好的例子是来自 Advanced Template 的 SignupForm:
<?php
namespace frontend\models;
use yii\base\Model;
use common\models\User;
/**
* Signup form
*/
class SignupForm extends Model
{
public $username;
public $email;
public $password;
/**
* @inheritdoc
*/
public function rules()
{
return [
['username', 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
];
}
/**
* Signs user up.
*
* @return User|null the saved model or null if saving fails
*/
public function signup()
{
if (!$this->validate()) {
return null;
}
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
return $user->save() ? $user : null;
}
}
如您所见,模型的验证和创建被隔离成单独的形式,这是更好的做法,而不是直接在模型中处理(尤其是文件上传)。但是为了简单的目的,只使用模型也是可以接受的。
我用 Gii 从数据库 table 中生成了一个模型 yii2.this 模型继承自 ActiveRecord 。然后我从这个 model.now 创建了一个表单我想用这个表单上传一个文件。 是否可以上传具有相同模型(继承自 ActiveRecord)的文件?
如果是,怎么办? 如果没有,我该怎么办?
是的,这是可能的,但使用单独的表格是更好的做法。它在文章 Uploading files
的官方文档中有详细描述创建单独的表单:
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;
}
}
}
渲染文件输入:
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'imageFile')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end() ?>
自定义控制器以处理文件上传:
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]);
}
}
本文还介绍了上传多个文件。
另见 this related question。
如果要与ActiveRecord
一起使用,并将文件路径保存为模型属性,可以在表单的upload()
方法中添加模型创建和保存。使用表单的另一个很好的例子是来自 Advanced Template 的 SignupForm:
<?php
namespace frontend\models;
use yii\base\Model;
use common\models\User;
/**
* Signup form
*/
class SignupForm extends Model
{
public $username;
public $email;
public $password;
/**
* @inheritdoc
*/
public function rules()
{
return [
['username', 'trim'],
['username', 'required'],
['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This username has already been taken.'],
['username', 'string', 'min' => 2, 'max' => 255],
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'string', 'max' => 255],
['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'This email address has already been taken.'],
['password', 'required'],
['password', 'string', 'min' => 6],
];
}
/**
* Signs user up.
*
* @return User|null the saved model or null if saving fails
*/
public function signup()
{
if (!$this->validate()) {
return null;
}
$user = new User();
$user->username = $this->username;
$user->email = $this->email;
$user->setPassword($this->password);
$user->generateAuthKey();
return $user->save() ? $user : null;
}
}
如您所见,模型的验证和创建被隔离成单独的形式,这是更好的做法,而不是直接在模型中处理(尤其是文件上传)。但是为了简单的目的,只使用模型也是可以接受的。