Yii框架实现图片上传的方法详解


Posted in PHP onMay 20, 2017

本文实例讲述了Yii框架实现图片上传的方法。分享给大家供大家参考,具体如下:

今天在网上看了下有关图片上传的教程,历经挫折才调试好,现在把相关代码及其说明贴出来,以供初次使用的朋友们参考。

Model:

<?php
class Upload extends CActiveRecord {
  public $image;
  public static function model($className = __CLASS__) {
    return $className;
  }
  public function tableName() {
    return '{{resource}}';
  }
  public function rules() {
    return array(
      array('image', 'file', 'types'=>'jpg, gif, png')
    );
  }
}

注:resource为数据表,表前缀可在main.php内设置,相信朋友们在看到文件上传时应该熟悉了main.php位置在哪及运作机制。

Controller:

<?php
class UploadController extends Controller {
  public function actionIndex() {
    $model=new Upload;
    if(isset($_POST['Upload'])) {
      $model->image=CUploadedFile::getInstance($model,'image');
      $ext = $model->image->getExtensionName();
      $fileName = uniqid() . '.' . $ext;
      $model->image->saveAs('assets/' . $fileName);
    }
    $this->renderPartial('index', array('model'=>$model));
  }
}

注:saveAs里面是存放图片上传后的地址,追踪下代码可以发现,该参数是move_uploaded_file函数的第二个参数,一定得是文件名。

View:

<meta charset="utf-8">
<?php echo CHtml::form(SITE_URL . 'admin/upload/index','post',array('enctype'=>'multipart/form-data')); ?>
<?php echo CHtml::activeFileField($model, 'image'); ?>
<?php echo CHtml::submitButton('提交');?>
<?php echo CHtml::endForm(); ?>

注:上面的SITE_URL为项目定义的常量,也就是项目的网址

相信经过上述步骤,朋友们应该可以上传成功图片,而且在项目下的assets目录下找到上传的图片。因为发现yii没有缩略图的方法,于是把thinkphp缩略图的方法整合了进来,把下面代码保存为Image.php放在项目下的protected/extensions目录下

<?php
class Image extends CController {
  /**
   +----------------------------------------------------------
   * 取得图像信息
   *
   +----------------------------------------------------------
   * @static
   * @access public
   +----------------------------------------------------------
   * @param string $image 图像文件名
   +----------------------------------------------------------
   * @return mixed
   +----------------------------------------------------------
   */
  static function getImageInfo($img) {
    $imageInfo = getimagesize($img);
    if ($imageInfo !== false) {
      $imageType = strtolower(substr(image_type_to_extension($imageInfo[2]), 1));
      $imageSize = filesize($img);
      $info = array(
        "width" => $imageInfo[0],
        "height" => $imageInfo[1],
        "type" => $imageType,
        "size" => $imageSize,
        "mime" => $imageInfo['mime']
      );
      return $info;
    } else {
      return false;
    }
  }
  /**
   +----------------------------------------------------------
   * 生成缩略图
   +----------------------------------------------------------
   * @static
   * @access public
   +----------------------------------------------------------
   * @param string $image 原图
   * @param string $type 图像格式
   * @param string $thumbname 缩略图文件名
   * @param string $maxWidth 宽度
   * @param string $maxHeight 高度
   * @param string $position 缩略图保存目录
   * @param boolean $interlace 启用隔行扫描
   +----------------------------------------------------------
   * @return void
   +----------------------------------------------------------
   */
  static function thumb($image, $thumbname, $type='', $maxWidth=200, $maxHeight=50, $interlace=true) {
    // 获取原图信息
    $info = Image::getImageInfo($image);
    if ($info !== false) {
      $srcWidth = $info['width'];
      $srcHeight = $info['height'];
      $type = empty($type) ? $info['type'] : $type;
      $type = strtolower($type);
      $interlace = $interlace ? 1 : 0;
      unset($info);
      $scale = min($maxWidth / $srcWidth, $maxHeight / $srcHeight); // 计算缩放比例
      if ($scale >= 1) {
        // 超过原图大小不再缩略
        $width = $srcWidth;
        $height = $srcHeight;
      } else {
        // 缩略图尺寸
        $width = (int) ($srcWidth * $scale);
        $height = (int) ($srcHeight * $scale);
      }
      // 载入原图
      $createFun = 'ImageCreateFrom' . ($type == 'jpg' ? 'jpeg' : $type);
      if(!function_exists($createFun)) {
        return false;
      }
      $srcImg = $createFun($image);
      //创建缩略图
      if ($type != 'gif' && function_exists('imagecreatetruecolor'))
        $thumbImg = imagecreatetruecolor($width, $height);
      else
        $thumbImg = imagecreate($width, $height);
       //png和gif的透明处理 by luofei614
      if('png'==$type){
        imagealphablending($thumbImg, false);//取消默认的混色模式(为解决阴影为绿色的问题)
        imagesavealpha($thumbImg,true);//设定保存完整的 alpha 通道信息(为解决阴影为绿色的问题)
      }elseif('gif'==$type){
        $trnprt_indx = imagecolortransparent($srcImg);
         if ($trnprt_indx >= 0) {
            //its transparent
            $trnprt_color = imagecolorsforindex($srcImg , $trnprt_indx);
            $trnprt_indx = imagecolorallocate($thumbImg, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
            imagefill($thumbImg, 0, 0, $trnprt_indx);
            imagecolortransparent($thumbImg, $trnprt_indx);
       }
      }
      // 复制图片
      if (function_exists("ImageCopyResampled"))
        imagecopyresampled($thumbImg, $srcImg, 0, 0, 0, 0, $width, $height, $srcWidth, $srcHeight);
      else
        imagecopyresized($thumbImg, $srcImg, 0, 0, 0, 0, $width, $height, $srcWidth, $srcHeight);
      // 对jpeg图形设置隔行扫描
      if ('jpg' == $type || 'jpeg' == $type)
        imageinterlace($thumbImg, $interlace);
      // 生成图片
      $imageFun = 'image' . ($type == 'jpg' ? 'jpeg' : $type);
      $imageFun($thumbImg, $thumbname);
      imagedestroy($thumbImg);
      imagedestroy($srcImg);
      return $thumbname;
    }
    return false;
  }
}
?>

再在项目下的protected/config/main.php中import字段加上

// autoloading model and component classes
  'import'=>array(
    'application.models.*',
    'application.components.*',
    'application.extensions.*',  #加上此行,意思为自动载入
  ),

再上面的Controller加上

public function actionIndex() {
    $model=new Upload;
    if(isset($_POST['Upload'])) {
      $model->image=CUploadedFile::getInstance($model,'image');
      $ext = $model->image->getExtensionName();
      $fileName = uniqid() . '.' . $ext;
      $model->image->saveAs('assets/' . $fileName);
      // 生成缩略图
      Image::thumb('assets/' . $fileName, 'assets/' . uniqid() . '.' . $ext);
    }
    $this->renderPartial('index', array('model'=>$model));
}

这次就完整了。

希望本文所述对大家基于Yii框架的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP模板引擎SMARTY
Oct 09 PHP
深入php socket的讲解与实例分析
Jun 13 PHP
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
Feb 18 PHP
php常用文件操作函数汇总
Nov 22 PHP
PHP设计模式之适配器模式代码实例
May 11 PHP
分享php分页的功能模块
Jun 16 PHP
PHP 错误处理机制
Jul 06 PHP
PHP易混淆知识整理笔记
Sep 24 PHP
解析WordPress中函数钩子hook的作用及基本用法
Dec 22 PHP
在WordPress中实现发送http请求的相关函数解析
Dec 29 PHP
PHP实现一个限制实例化次数的类示例
Sep 16 PHP
php中用unset销毁变量并释放内存
May 10 PHP
Yii框架分页实现方法详解
May 20 #PHP
thinkPHP显示不出验证码的原因与解决方法分析
May 20 #PHP
yii2项目实战之restful api授权验证详解
May 20 #PHP
ThinkPHP下表单令牌错误与解决方法分析
May 20 #PHP
PHP那些琐碎的知识点(整理)
May 20 #PHP
PHP使用xpath解析XML的方法详解
May 20 #PHP
PHP CodeIgniter分页实例及多条件查询解决方案(推荐)
May 20 #PHP
You might like
php 获取一个月第一天与最后一天的代码
2010/05/16 PHP
php在项目中寻找代码的坏味道(综艺命名)
2012/07/19 PHP
朋友网关于QQ相关的PHP代码(研究QQ的绝佳资料)
2015/01/26 PHP
php通过PHPExcel导入Excel表格到MySQL数据库的简单实例
2016/10/29 PHP
PHP设计模式之单例模式原理与实现方法分析
2018/04/25 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
Laravel 实现关系模型取出需要的字段
2019/10/10 PHP
关于eval 与new Function 到底该选哪个?
2013/04/17 Javascript
JQuery 使用attr方法实现下拉列表选中
2014/10/13 Javascript
js中的json对象详细介绍
2014/10/29 Javascript
jQuery基础知识小结
2014/12/22 Javascript
详解Bootstrap创建表单的三种格式(一)
2016/01/04 Javascript
javascript特效实现——当前时间和倒计时效果的简单实例
2016/07/20 Javascript
使用jquery实现的循环连续可停顿滚动实例
2016/11/23 Javascript
完美实现js选项卡切换效果(一)
2017/03/08 Javascript
Angular中管道操作符(|)的使用方法
2017/12/15 Javascript
微信小程序scroll-view实现滚动穿透和阻止滚动的方法
2018/08/20 Javascript
JavaScript数组方法的错误使用例子
2018/09/13 Javascript
angular6的响应式表单的实现
2018/10/10 Javascript
ES6 系列之 Generator 的自动执行的方法示例
2018/10/19 Javascript
node.js 使用 net 模块模拟 websocket 握手进行数据传递操作示例
2020/02/11 Javascript
jQuery实现动态操作table行
2020/11/23 jQuery
[01:01:52]完美世界DOTA2联赛PWL S2 GXR vs Magma 第二场 11.25
2020/11/26 DOTA
Python根据区号生成手机号码的方法
2015/07/08 Python
python分布式环境下的限流器的示例
2017/10/26 Python
Python多进程库multiprocessing中进程池Pool类的使用详解
2017/11/24 Python
Python对象与引用的介绍
2019/01/24 Python
如何关掉pycharm中的python console(图解)
2019/10/31 Python
8款使用 CSS3 实现超炫的 Loading(加载)的动画效果
2015/03/17 HTML / CSS
澳大利亚电子产品购物网站:Dick Smith
2017/02/02 全球购物
为什么要使用servlet
2016/01/17 面试题
医院实习介绍信
2014/01/12 职场文书
晨会主持词
2014/03/17 职场文书
单位接收函格式
2015/01/30 职场文书
2016年感恩节活动总结大全
2016/04/01 职场文书
SQL SERVER实现连接与合并查询
2022/02/24 SQL Server