Yii2 如何在控制器给模型赋初值? [ 2.0 版本 ]
最近在开发一个图片上传和文件上传的功能。我写了个文件上传的模型 FileUpload
,里面有一个允许文件上传的格式变量 $allowType = ['jpg', 'png', 'gif'];
,里面一个init()
方法对上传过来的文件进行处理,还有一个 save()
的方法,对文件进行保存处理。然后我在控制器写了两个方法,一个是图片上传的方法ImageUpload()
,另一个是文件上传的方法 FileUpload()
。然后我在 FileUpload()
这个方法内,对$allowType
增加了一个txt,即 $allowType=['jpg', 'png', 'gif', 'txt'];
,代码如下:
public function actionFileUpload()
{
Yii::$app->response->format = Response::FORMAT_JSON;
$model = New FileUpload();
$model->fileInputName = 'name';
$model->mimetype = ['jpg', 'png', 'gif', 'txt'];
$model->allowType = ['image/jpeg', 'image/bmp', 'image/gif', 'image/png', 'image/pjpeg', 'image/x-png', 'text/plain'];
$model->savePath = Yii::getAlias('@frontend/web/upload/file');
if($model->save()){
return [
'code' => 1,
'msg' => $model->getMessage(),
'data' => [
'url' => $model->getUrlPath()
]
];
}else{
return [
'code' => 0,
'msg' => $model->getMessage()
];
}
}
可是发现txt的文件还是没法上传,就是 $model->allowType
这样不会对模型里面的 $allowType
重新赋值,它依旧只是认得它自带的值,难道只能模型传值给控制器,而控制器不能对模型重新赋值吗?
附上FileUpload模型的相关代码:
`namespace common\models;
use yii;
use yii\base\Object;
use yii\helpers\FileHelper;
use yii\web\UploadedFile;
class FileUpload extends Object
{
// 最大可上传大小
public $maxsize = 1024100000;
// 可上传的文件类型
public $mimetype = ['jpg', 'png', 'jpeg', 'gif', 'bmp'];
// 允许的类型
public $allowType = ['image/jpeg', 'image/bmp', 'image/gif', 'image/png', 'image/pjpeg', 'image/x-png'];
// 上传表单 file name
public $fileInputName = 'file';
// 图像保存根位置
public $savePath;
// 上传文件
private $_uploadFile;
// 文件路径
private $filePath;
// 访问路径
private $urlPath;
// 返回状态
private $res = false;
// 返回信息
private $message;
public function init()
{
if (!$this->fileInputName){
$this->message = 'fileInputName属性不能为空';
return [
'code' => 0,
'msg' => $this->message,
];
}
if (!$this->savePath) {
$this->savePath = Yii::getAlias('@frontend/web/upload/images');
}
$this->savePath = rtrim($this->savePath,'/');
if(!file_exists($this->savePath)){
if(! FileHelper::createDirectory($this->savePath)){
$this->message = '没有权限创建'.$this->savePath;
return [
'code' => 0,
'msg' => $this->message,
];
}
}
$this->_uploadFile = UploadedFile::getInstanceByName($this->fileInputName);
// 获取文件名
$fileName = $this->_uploadFile->baseName;
// 获取文件格式
$fileType = $this->_uploadFile->type;
// 获取文件后缀
$fileExtension = $this->_uploadFile->extension;
// 获取文件大小
$fileSize = $this->_uploadFile->size;
// 获取文件错误
$fileError = $this->_uploadFile->error;
if(!$this->_uploadFile){
$this->message = '没有找到上传文件';
return [
'code' => 0,
'msg' => $this->message,
];
}
if($fileError){
$this->message = '文件上传失败';
return [
'code' => 0,
'msg' => $this->message,
];
}
if($fileSize > $this->maxsize){
$this->message = '上传的文件大小受限制';
return [
'code' => 0,
'msg' => $this->message,
];
}
if(!in_array($fileExtension, $this->mimetype) || !in_array($fileType, $this->allowType)){
$this->message = '该文件类型不允许上传';
return [
'code' => 0,
'msg' => $this->message,
];
}
$YearDir = date('Y',time());
$MonthDayDir = date('md',time());
if(!file_exists($this->savePath.'/'.$YearDir.'/'.$MonthDayDir)){
FileHelper::createDirectory($this->savePath.'/'.$YearDir.'/'.$MonthDayDir);
}
$randomName = mt_rand(1000, 9999);
$newTimestamp = time();
$this->filePath = $this->savePath.'/'.$YearDir.'/'.$MonthDayDir.'/'.$newTimestamp.$randomName.'.'.$fileExtension;
$this->urlPath = '/upload/images/'.$YearDir.'/'.$MonthDayDir.'/'.$newTimestamp.$randomName.'.'.$fileExtension;
}
public function save()
{
if($this->_uploadFile->saveAs($this->filePath)){
$this->res = true;
}else{
$this->res = false;
}
if($this->res){
$this->message = '文件上传成功!';
}else{
$this->message = '文件上传失败!';
}
return $this->res;
}
public function getMessage(){
return $this->message;
}
public function getUrlPath(){
return $this->urlPath;
}
}`
最佳答案
-
liujingxing 发布于 2018-11-14 09:45 举报
因为你的 FileUpload 继承的 Object 类,Object 类在实例化的时候,就会调用init() 方法
public function __construct($config = []) { if (!empty($config)) { Yii::configure($this, $config); } $this->init(); }
所以你现在的报错是在new FileUpload() 就报错了, 你下面修改类的属性都还没有执行,并不是不能修改!
如果你要修改类的属性,直接在new FileUpload() 时候传递一个数组就可以了(属性对应属性值)$model = New FileUpload([ 'fileInputName' => 'name', 'allowType' => ['jpg', 'png', 'gif', 'txt'], 'mimetype' => ['image/jpeg', 'image/bmp', 'image/gif', 'image/png', 'image/pjpeg', 'image/x-png', 'text/plain'], 'savePath' => Yii::getAlias('@frontend/web/upload/file') ]);
这样就可以了!
另外:个人建议 FileUpload 需要将功能拆分,上传验证交给 model, FileUpload 只负责调用 model 验证,以及处理上传路径问题
附代码:
- 上传model
<?php namespace frontend\models; use yii\base\Model; class UploadForm extends Model { public $name; public $file; /** * 设置验证场景 * * @return array */ public function scenarios() { return [ 'name' => ['name'], 'file' => ['file'], ]; } /** * {@inheritdoc} */ public function rules() { // 我这里是偷懒的写法,就是多个上传字段,使用一个上传验证类, 只要添加验证场景和验证字段规则就好了 return [ [ ['name'], 'file', 'extensions' => ['jpg', 'png', 'gif', 'txt'], 'maxSize' => 1024100000, // 'checkExtensionByMimeType' => false, // 要不要验证 mimeTypes 类型 'mimeTypes' => ['image/jpeg', 'image/bmp', 'image/gif', 'image/png', 'image/pjpeg', 'image/x-png', 'text/plain'], 'on' => 'name', ], [ ['file'], 'image', 'extensions' => ['jpg', 'png', 'gif'], 'maxSize' => 1024100000, 'on' => 'file', ] ]; } }
- FileUpload 代码
<?php namespace frontend\models; use yii; use yii\base\Object; use yii\helpers\FileHelper; use yii\web\UploadedFile; class FileUpload extends Object { /** * @var \yii\base\Model 处理的model */ public $model; /** * @var string 上传文件表单名称 */ public $fileInputName = 'file'; /** * @var string 图片保存绝对路径 */ public $savePath; /** * @var string 文件访问路径前缀 */ public $urlPathPrefix = '/upload/images'; /** * @var UploadedFile 上传文件处理类 */ private $uploadFile; /** * @var string 文件保存路径 */ private $filePath; /** * @var string 文件访问路径 */ private $urlPath; /** * @return array|void * @throws yii\base\Exception */ public function init() { if (!$this->savePath) { $this->savePath = Yii::getAlias('@frontend/web/upload/images'); } // 目录不存在创建 $this->savePath = rtrim($this->savePath, '/'); if (!file_exists($this->savePath) && !FileHelper::createDirectory($this->savePath)) { throw new yii\base\Exception('没有权限创建' . $this->savePath); } if (empty($this->model) || !($this->model instanceof Model)) { throw new yii\base\Exception('没有传递上传文件类'); } // 上传文件接收 $strField = $this->fileInputName; $this->model->$strField = $this->uploadFile = UploadedFile::getInstanceByName($this->fileInputName); if (empty($this->uploadFile)) { throw new yii\base\Exception('没有上传文件'); } // 上传文件验证 if (!$this->model->validate()) { throw new yii\base\Exception($this->model->getFirstError($strField)); } list($path, $datePath) = $this->createDir($this->savePath); $fileName = time() . mt_rand(1000, 9999) . '.' . $this->uploadFile->getExtension(); $this->filePath = $path . $fileName; $this->urlPath = rtrim($this->urlPathPrefix, '/') . '/' . $datePath . '/' . $fileName; } /** * 根据时间创建目录 * * @param $path * * @return array * * @throws yii\base\Exception */ public function createDir($path) { $datePath = date('Y') . '/' . date('md'); $path = $path . '/' . $datePath . '/'; if (!file_exists($path)) { FileHelper::createDirectory($path); } return [$path, $datePath]; } public function save() { return $this->uploadFile->saveAs($this->filePath); } public function getUrlPath() { return $this->urlPath; } }
- 控制器调用
public function actionFileUpload() { try { $model = New FileUpload([ 'fileInputName' => 'name', 'model' => new UploadForm(['scenario' => 'name']), 'savePath' => Yii::getAlias('@frontend/web/upload/file'), 'urlPathPrefix' => '/upload/file' ]); if (!$model->save()) { throw new \Exception('上传文件失败'); } return $this->asJson([ 'code' => 1, 'msg' => '上传文件成功', 'data' => ['url' => $model->getUrlPath()] ]); } catch (\Exception $e) { return $this->asJson(['code' => 0, 'msg' => $e->getMessage()]); } }
共 1 条回复clao , return19931112 觉得很赞
其他 4 个回答
-
return19931112 回答于 2018-11-13 15:45 举报
FileUpload代码贴一下,无论是模型还是控制器,都只是PHP的class,不存在模型的值只能在控制器中修改之类的问题
共 3 条回复return19931112 回复于 2018-11-13 16:08 回复@clao 大兄弟,你看看你的controller代码
$model->allowType = ['jpg', 'png', 'gif', 'txt']; $model->allowType = ['image/jpeg', 'image/bmp', 'image/gif', 'image/png', 'image/pjpeg', 'image/x-png', 'text/plain'];
下面的allowType覆盖上面的allowType了,自然没办法上传.txt文件
clao
最后登录:2022-01-25
在线时长:9小时19分
- 粉丝1
- 金钱80
- 威望20
- 积分370