thinkphp文件上傳以及圖片處理

文件上傳

上傳表單

在ThinkPHP中使用上傳功能無需進行特別處理。例如,下面是一個帶有附件上傳的表單提交:數組

<form action="__URL__/upload" enctype="multipart/form-data" method="post" >
<input type="text" name="name" />
<input type="file" name="photo" />
<input type="submit" value="提交" >
</form>

注意,要使用上傳功能 你的表單須要設置 enctype="multipart/form-data"安全

多文件上傳支持

若是須要使用多個文件上傳,只須要修改表單,把服務器

<input type='file'  name='photo'>

改成函數

<input type='file'  name='photo1'>
<input type='file'  name='photo2'>
<input type='file'  name='photo3'>

或者post

<input type='file'  name='photo[]'>
<input type='file'  name='photo[]'>
<input type='file'  name='photo[]'>

兩種方式的多附件上傳系統的文件上傳類均可以自動識別。字體

上傳操做

ThinkPHP文件上傳操做使用Think\Upload類,假設前面的表單提交到當前控制器的upload方法,咱們來看下upload方法的實現代碼:ui

public function upload(){
    $upload = new \Think\Upload();// 實例化上傳類
    $upload->maxSize   =     3145728 ;// 設置附件上傳大小
    $upload->exts      =     array('jpg', 'gif', 'png', 'jpeg');// 設置附件上傳類型
    $upload->rootPath  =     './Uploads/'; // 設置附件上傳根目錄
    $upload->savePath  =     ''; // 設置附件上傳(子)目錄
    // 上傳文件 
    $info   =   $upload->upload();
    if(!$info) {// 上傳錯誤提示錯誤信息
        $this->error($upload->getError());
    }else{// 上傳成功
        $this->success('上傳成功!');
    }
}

上傳類對圖片文件的上傳安全作了支持,若是企圖上傳非法的圖像文件,系統會提示 非法圖像文件。 爲了更好的使用上傳功能,建議你的服務器開啓finfo模塊支持this

上傳參數

在上傳操做以前,咱們能夠對上傳的屬性進行一些設置,Upload類支持的屬性設置包括:編碼

屬性 描述
maxSize 文件上傳的最大文件大小(以字節爲單位),0爲不限大小
rootPath 文件上傳保存的根路徑
savePath 文件上傳的保存路徑(相對於根路徑)
saveName 上傳文件的保存規則,支持數組和字符串方式定義
saveExt 上傳文件的保存後綴,不設置的話使用原文件後綴
replace 存在同名文件是不是覆蓋,默認爲false
exts 容許上傳的文件後綴(留空爲不限制),使用數組或者逗號分隔的字符串設置,默認爲空
mimes 容許上傳的文件類型(留空爲不限制),使用數組或者逗號分隔的字符串設置,默認爲空
autoSub 自動使用子目錄保存上傳文件 默認爲true
subName 子目錄建立方式,採用數組或者字符串方式定義
hash 是否生成文件的hash編碼 默認爲true
callback 檢測文件是否存在回調,若是存在返回文件信息數組

上面的屬性能夠經過兩種方式傳入:3d

實例化傳入

咱們能夠在實例化的時候直接傳入參數數組,例如:

$config = array(
    'maxSize'    =>    3145728,
    'rootPath'   =>    './Uploads/',
    'savePath'   =>    '',
    'saveName'   =>    array('uniqid',''),
    'exts'       =>    array('jpg', 'gif', 'png', 'jpeg'),
    'autoSub'    =>    true,
    'subName'    =>    array('date','Ymd'),
);
$upload = new \Think\Upload($config);// 實例化上傳類

關於saveName和subName的使用後面咱們會有詳細的描述。

動態賦值

支持在實例化後動態賦值上傳參數,例如:

$upload = new \Think\Upload();// 實例化上傳類
$upload->maxSize = 3145728;
$upload->rootPath = './Uploads/';
$upload->savePath = '';
$upload->saveName = array('uniqid','');
$upload->exts     = array('jpg', 'gif', 'png', 'jpeg');
$upload->autoSub  = true;
$upload->subName  = array('date','Ymd');

上面的設置和實例化傳入的效果是一致的。

上傳文件信息

設置好上傳的參數後,就能夠調用Think\Upload類的upload方法進行附件上傳,若是失敗,返回false,而且用getError方法獲取錯誤提示信息;若是上傳成功,就返回成功上傳的文件信息數組。

$upload = new \Think\Upload();// 實例化上傳類
$upload->maxSize   =     3145728 ;// 設置附件上傳大小
$upload->exts      =     array('jpg', 'gif', 'png', 'jpeg');// 設置附件上傳類型
$upload->rootPath  =      './Uploads/'; // 設置附件上傳根目錄
$upload->savePath  =      ''; // 設置附件上傳(子)目錄
// 上傳文件 
$info   =   $upload->upload();
if(!$info) {// 上傳錯誤提示錯誤信息
    $this->error($upload->getError());
}else{// 上傳成功 獲取上傳文件信息
    foreach($info as $file){
        echo $file['savepath'].$file['savename'];
    }
}

每一個文件信息又是一個記錄了下面信息的數組,包括:

屬性 描述
key 附件上傳的表單名稱
savepath 上傳文件的保存路徑
name 上傳文件的原始名稱
savename 上傳文件的保存名稱
size 上傳文件的大小
type 上傳文件的MIME類型
ext 上傳文件的後綴類型
md5 上傳文件的md5哈希驗證字符串 僅當hash設置開啓後有效
sha1 上傳文件的sha1哈希驗證字符串 僅當hash設置開啓後有效

文件上傳成功後,就能夠使用這些文件信息來進行其餘的數據操做,例如保存到當前數據表或者單獨的附件數據表。

例如,下面表示把上傳信息保存到數據表的字段:

$model = M('Photo');
// 取得成功上傳的文件信息
$info = $upload->upload();
// 保存當前數據對象
$data['photo'] = $info['photo']['savename'];
$data['create_time'] = NOW_TIME;
$model->add($data);

單文件上傳

upload方法支持多文件上傳,有時候,咱們只須要上傳一個文件,就能夠使用Upload類提供的uploadOne方法上傳單個文件,例如:

public function upload(){
    $upload = new \Think\Upload();// 實例化上傳類
    $upload->maxSize   =     3145728 ;// 設置附件上傳大小
    $upload->exts      =     array('jpg', 'gif', 'png', 'jpeg');// 設置附件上傳類型
    $upload->rootPath  =      './Uploads/'; // 設置附件上傳根目錄
    // 上傳單個文件 
    $info   =   $upload->uploadOne($_FILES['photo1']);
    if(!$info) {// 上傳錯誤提示錯誤信息
        $this->error($upload->getError());
    }else{// 上傳成功 獲取上傳文件信息
         echo $info['savepath'].$info['savename'];
    }
}

uploadOne方法上傳成功後返回的文件信息和upload方法的區別是隻有單個文件信息的一維數組。

上傳文件的命名規則

上傳文件的命名規則(saveName)用於確保文件不會產生衝突或者覆蓋的狀況。命名規則的定義能夠根據你的業務邏輯來調整,不是固定的。例如,若是你採用時間戳的方式來定義命名規範,那麼在同時上傳多個文件的時候可能產生衝突(由於同一秒內能夠上傳多個文件),所以你須要根據你的業務需求來設置合適的上傳命名規則。這裏順便來講下saveName參數的具體用法。

採用函數方式

若是傳入的字符串是一個函數名,那麼表示採用函數動態生成上傳文件名(不包括文件後綴),例如:

// 採用時間戳命名
$upload->saveName = 'time';
// 採用GUID序列命名
$upload->saveName = 'com_create_guid';

也能夠採用用戶自定義函數

// 採用自定義函數命名
$upload->saveName = 'myfun';

默認的命名規則設置是採用uniqid函數生成一個惟一的字符串序列。

saveName的值支持數組和字符串兩種方式,若是是隻有一個參數或者沒有參數的函數,直接使用字符串設置便可,若是須要傳入額外的參數,能夠使用數組方式,例如:

// 採用date函數生成命名規則 傳入Y-m-d參數
$upload->saveName = array('date','Y-m-d'); 
// 若是有多個參數須要傳入的話 能夠使用數組
$upload->saveName = array('myFun',array('__FILE__','val1','val2'));

若是須要使用上傳的原始文件名,能夠採用**FILE**傳入,因此上面的定義規則,最終的結果是 myFun('上傳文件名','val1','val2')執行的結果。

直接設置上傳文件名

若是傳入的參數不是一個函數名,那麼就會直接當作是上傳文件名,例如:

$upload->saveName = time().'_'.mt_rand();

表示上傳的文件命名採用時間戳加一個隨機數的組合字符串方式。

固然,若是以爲有必要,你還能夠固定設置一個上傳文件的命名規則,用於固定保存某個上傳文件。

$upload->saveName = 'ThinkPHP';

保持上傳文件名不變

若是你想保持上傳的文件名不變,那麼只須要設置命名規範爲空便可,例如:

$upload->saveName = '';

通常來講不建議保持不變,由於會致使相同的文件名上傳後被覆蓋的狀況。

子目錄保存

saveName只是用於設置文件的保存規則,不涉及到目錄,若是但願對上傳的文件分子目錄保存,能夠設置autoSubsubName參數來完成,例如:

// 開啓子目錄保存 並以日期(格式爲Ymd)爲子目錄
$upload->autoSub = true;
$upload->subName = array('date','Ymd');

能夠使用自定義函數來保存,例如:

// 開啓子目錄保存 並調用自定義函數get_user_id生成子目錄
$upload->autoSub = true;
$upload->subName = 'get_user_id';

和saveName參數同樣,subName的定義能夠採用數組和字符串的方式。

注意:若是get_user_id函數未定義的話,會直接以get_user_id字符串做爲子目錄的名稱保存。

子目錄保存和文件命名規則能夠結合使用。

上傳驅動

上傳類能夠支持不一樣的環境,經過相應的上傳驅動來解決,默認狀況下使用本地(Local)上傳驅動,固然,你還能夠設置當前默認的上傳驅動類型,例如:

'FILE_UPLOAD_TYPE'    =>    'Ftp',
'UPLOAD_TYPE_CONFIG'  =>    array(        
        'host'     => '192.168.1.200', //服務器
        'port'     => 21, //端口
        'timeout'  => 90, //超時時間
        'username' => 'ftp_user', //用戶名
        'password' => 'ftp_pwd', //密碼 ),

表示當前使用Ftp做爲上傳類的驅動,上傳的文件會經過FTP傳到指定的遠程服務器。

也能夠在實例化上傳類的時候指定,例如:

$config = array(
    'maxSize'    =    3145728,
    'rootPath'   =    './Uploads/',
    'savePath'   =    '',
    'saveName'   =    array('uniqid',''),
    'exts'       =    array('jpg', 'gif', 'png', 'jpeg'),
    'autoSub'    =    true,
    'subName'    =    array('date','Ymd'),
);
$ftpConfig     =    array(        
        'host'     => '192.168.1.200', //服務器
        'port'     => 21, //端口
        'timeout'  => 90, //超時時間
        'username' => 'ftp_user', //用戶名
        'password' => 'ftp_pwd', //密碼 );

$upload = new \Think\Upload($config,'Ftp',$ftpConfig);// 實例化上傳類

圖像處理

使用Think\Image類進行圖像處理功能,支持Gd庫和Imagick庫,包括對GIf圖像處理的支持。

實例化類庫

$image = new \Think\Image();

默認使用GD庫進行圖像操做,若是須要使用Imagick庫操做的話,須要改爲:

$image = new \Think\Image(\Think\Image::IMAGE_IMAGICK); 
// 或者採用
$image = new \Think\Image('Imagick');

圖像操做

下面來看下基礎的圖像操做功能的使用方法。

打開圖像文件

假設當前入口文件目錄下面有一個1.jpg文件,如圖所示:

1

使用open方法打開圖像文件進行相關操做:

$image = new \Think\Image(); 
$image->open('./1.jpg');

也能夠簡化成下面的方式:

$image = new \Think\Image(\Think\Image::IMAGE_GD,'./1.jpg'); // GD庫
// 或者
$image = new \Think\Image(\Think\Image::IMAGE_IMAGICK,'./1.jpg');  // imagick庫

獲取圖像信息

能夠獲取打開圖片的信息,包括圖像大小、類型等,例如:

$image = new \Think\Image(); 
$image->open('./1.jpg');
$width = $image->width(); // 返回圖片的寬度
$height = $image->height(); // 返回圖片的高度
$type = $image->type(); // 返回圖片的類型
$mime = $image->mime(); // 返回圖片的mime類型
$size = $image->size(); // 返回圖片的尺寸數組 0 圖片寬度 1 圖片高度

裁剪圖片

使用crop和save方法完成裁剪圖片功能。

$image = new \Think\Image(); 
$image->open('./1.jpg');
//將圖片裁剪爲400x400並保存爲corp.jpg
$image->crop(400, 400)->save('./crop.jpg');

生成的圖片如圖:

crop

支持從某個座標開始裁剪,例以下面從(100,30)開始裁剪:

$image = new \Think\Image(); 
$image->open('./1.jpg');
//將圖片裁剪爲400x400並保存爲corp.jpg
$image->crop(400, 400,100,30)->save('./crop.jpg');

生成的圖片如圖:

crop

生成縮略圖

使用thumb方法生成縮略圖

$image = new \Think\Image(); 
$image->open('./1.jpg');
// 按照原圖的比例生成一個最大爲150*150的縮略圖並保存爲thumb.jpg
$image->thumb(150, 150)->save('./thumb.jpg');

生成的縮略圖如圖所示:

thumb

咱們看到實際生成的縮略圖並非150*150,由於默認採用原圖等比例縮放的方式生成縮略圖,最大寬度是150。

能夠支持其餘類型的縮略圖生成,設置包括Think\Image的下列常量或者對應的數字:

IMAGE_THUMB_SCALE     =   1 ; //等比例縮放類型
IMAGE_THUMB_FILLED    =   2 ; //縮放後填充類型
IMAGE_THUMB_CENTER    =   3 ; //居中裁剪類型
IMAGE_THUMB_NORTHWEST =   4 ; //左上角裁剪類型
IMAGE_THUMB_SOUTHEAST =   5 ; //右下角裁剪類型
IMAGE_THUMB_FIXED     =   6 ; //固定尺寸縮放類型

例如:

居中裁剪

$image = new \Think\Image(); 
$image->open('./1.jpg');
// 生成一個居中裁剪爲150*150的縮略圖並保存爲thumb.jpg
$image->thumb(150, 150,\Think\Image::IMAGE_THUMB_CENTER)->save('./thumb.jpg');

居中裁剪後生成的縮略圖效果如圖:

thumb

左上角剪裁

$image = new \Think\Image(); 
$image->open('./1.jpg');
// 生成一個左上角裁剪爲150*150的縮略圖並保存爲thumb.jpg
$image->thumb(150, 150,\Think\Image::IMAGE_THUMB_NORTHWEST)->save('./thumb.jpg');

左上角裁剪後生成的縮略圖效果如圖:

thumb

縮放填充

$image = new \Think\Image(); 
$image->open('./1.jpg');
// 生成一個縮放後填充大小150*150的縮略圖並保存爲thumb.jpg
$image->thumb(150, 150,\Think\Image::IMAGE_THUMB_FILLED)->save('./thumb.jpg');

縮放填充後生成的縮略圖效果如圖:

thumb

固定大小

$image = new \Think\Image(); 
$image->open('./1.jpg');
// 生成一個固定大小爲150*150的縮略圖並保存爲thumb.jpg
$image->thumb(150, 150,\Think\Image::IMAGE_THUMB_FIXED)->save('./thumb.jpg');

採用固定大小的縮略圖可能會有所變形,生成的縮略圖效果如圖:

thumb

添加圖片水印

$image = new \Think\Image(); 
$image->open('./1.jpg');
//將圖片裁剪爲440x440並保存爲corp.jpg
$image->crop(440, 440)->save('./crop.jpg');
// 給裁剪後的圖片添加圖片水印(水印文件位於./logo.png),位置爲右下角,保存爲water.gif
$image->water('./logo.png')->save("water.gif");
// 給原圖添加水印並保存爲water_o.gif(須要從新打開原圖)
$image->open('./1.jpg')->water('./logo.png')->save("water_o.gif");

water方法的第二個參數表示水印的位置,能夠傳入下列Think\Image類的常量或者對應的數字:

IMAGE_WATER_NORTHWEST =   1 ; //左上角水印
IMAGE_WATER_NORTH     =   2 ; //上居中水印
IMAGE_WATER_NORTHEAST =   3 ; //右上角水印
IMAGE_WATER_WEST      =   4 ; //左居中水印
IMAGE_WATER_CENTER    =   5 ; //居中水印
IMAGE_WATER_EAST      =   6 ; //右居中水印
IMAGE_WATER_SOUTHWEST =   7 ; //左下角水印
IMAGE_WATER_SOUTH     =   8 ; //下居中水印
IMAGE_WATER_SOUTHEAST =   9 ; //右下角水印

例如:

$image = new \Think\Image(); 
// 在圖片左上角添加水印(水印文件位於./logo.png) 並保存爲water.jpg
$image->open('./1.jpg')->water('./logo.png',\Think\Image::IMAGE_WATER_NORTHWEST)->save("water.jpg");

生成的圖片效果以下:

water

還能夠支持水印圖片的透明度(0~100,默認值是80),例如:

$image = new \Think\Image(); 
// 在圖片左上角添加水印(水印文件位於./logo.png) 水印圖片的透明度爲50 並保存爲water.jpg
$image->open('./1.jpg')->water('./logo.png',\Think\Image::IMAGE_WATER_NORTHWEST,50)->save("water.jpg");

生成的效果以下:

water

也能夠支持給圖片添加文字水印(假設在入口文件的同級目錄下存在1.ttf字體文件),例如:

$image = new \Think\Image(); 
// 在圖片右下角添加水印文字 ThinkPHP 並保存爲new.jpg
$image->open('./1.jpg')->text('ThinkPHP','./1.ttf',20,'#000000',\Think\Image::IMAGE_WATER_SOUTHEAST)->save("new.jpg");

生成的圖片效果:

new

目前已經支持的上傳驅動包括Local、Ftp、Sae、Bcs、七牛和又拍雲等。

相關文章
相關標籤/搜索