yii为我们提供了上传类,可以拿来使用。
由于我使用的高级版本,并且重新规划了入口文件,所以需要定义web目录
index.php
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../common/config/bootstrap.php');
require(__DIR__ . '/../frontend/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../common/config/main.php'),
require(__DIR__ . '/../common/config/main-local.php'),
require(__DIR__ . '/../frontend/config/main.php'),
require(__DIR__ . '/../frontend/config/main-local.php')
);
(new yii\web\Application($config))->run();
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require(__DIR__ . '/../../vendor/autoload.php');
require(__DIR__ . '/../../vendor/yiisoft/yii2/Yii.php');
require(__DIR__ . '/../../common/config/bootstrap.php');
require(__DIR__ . '/../../backend/config/bootstrap.php');
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../../backend/config/main.php'),
require(__DIR__ . '/../../backend/config/main-local.php')
);
(new yii\web\Application($config))->run();
首先定义上传目录并在web目录下新建上传目录:
定义在common/config/bootstrap.php中定义:
Yii::setAlias('@mywebroot', dirname(dirname(__DIR__)) . '/web');
Yii::setAlias('@uploads', dirname(dirname(__DIR__)) . '/web/uploads');
在上传文件中有2个方法:
方法1:
/**
* Returns an uploaded file for the given model attribute.
* The file should be uploaded using [[\yii\widgets\ActiveField::fileInput()]].
* @param \yii\base\Model $model the data model
* @param string $attribute the attribute name. The attribute name may contain array indexes.
* For example, '[1]file' for tabular file uploading; and 'file[1]' for an element in a file array.
* @return UploadedFile the instance of the uploaded file.
* Null is returned if no file is uploaded for the specified model attribute.
* @see getInstanceByName()
*/
public static function getInstance($model, $attribute)
{
$name = Html::getInputName($model, $attribute);
return static::getInstanceByName($name);
}
方法2:
/**
* Returns an uploaded file according to the given file input name.
* The name can be a plain string or a string like an array element (e.g. 'Post[imageFile]', or 'Post[0][imageFile]').
* @param string $name the name of the file input field.
* @return null|UploadedFile the instance of the uploaded file.
* Null is returned if no file is uploaded for the specified name.
*/
public static function getInstanceByName($name)
{
$files = self::loadFiles();
return isset($files[$name]) ? new static($files[$name]) : null;
}
我们使用第二种方法
再建立UploadForm.php,代码如下:
<?php
namespace common\models;
use Yii;
use yii\base\Model;
use yii\web\UploadedFile;
/**
* This is the model class for upload.
*
* @property string $path
*/
class UploadForm extends Model{
/**
* 上传图片
* @image_type common, news, product, cases, ad, category, downloads, friend_link
*
*/
public static function uploads($upfile, $old_image = '', $image_type = 'common'){
$upload_time = date("Ymd");
$upload_type_path = $image_type . '/' . $upload_time . '/';
//上传路径
$upload_save_path = Yii::getAlias('@uploads') . '/' . $upload_type_path;
if(!file_exists($upload_save_path)){
@mkdir($upload_save_path);
}
//保存路径
$upload_save_url = yii::$app->params['uploads_dir'] . '/' . $upload_type_path;
$uploaded_file=UploadedFile::getInstanceByName($upfile);
if($uploaded_file === null || $uploaded_file->hasError){
return $old_image;
}
//图片名称
$file_name = $uploaded_file->getBaseName();
//图片格式
$file_ext = $uploaded_file->getExtension();
//新文件名
$new_file_name=date("YmdHis") . rand(10000,99999). '.' .$file_ext;
//删除旧文件
if(!empty($old_image)){
@unlink(Yii::getAlias('@mywebroot') . '/' . $old_image);
}
$uploaded_file->saveAs($upload_save_path . $new_file_name);
return $upload_save_url . $new_file_name;
}
}
?>
则可以在News的ActiveRecord中使用上传功能, yii为我们提供了一个函数:beforeSave:
源码中有这样一段:
public function beforeSave($insert)
{
$event = new ModelEvent;
$this->trigger($insert ? self::EVENT_BEFORE_INSERT : self::EVENT_BEFORE_UPDATE, $event);
return $event->isValid;
}
所以他对update同样有效:
那我们就可以在beforeSave中上传图片:
public function beforeSave($insert)
{
$old_image = Yii::$app->request->post()['old_image'];
$uploaded_file=UploadForm::uploads("News[image]", $old_image, 'news');
$this->image = $uploaded_file;
return parent::beforeSave($insert);
}