clao
这个貌似只有编辑更新的时候有记录,添加和删除应该没有被记录
- clao 回复了 liujingxing 的回答
因为你的 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()]); } }
遇到大神了,谢谢你,按你的方法,可以了,感激~
- clao 赞了回答
因为你的 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()]); } }
- clao 回复了 return19931112 的回答
FileUpload代码贴一下,无论是模型还是控制器,都只是PHP的class,不存在模型的值只能在控制器中修改之类的问题
@我马上去拯救地球 不好意思,写错了,上面那个是$model->mimetype = ['jpg', 'png', 'gif', 'txt']; 不是$model->allowType = ['jpg', 'png', 'gif', 'txt'];,这一样没法上传txt