1. 程式人生 > >關於jquery.fileupload結合PHP上傳圖片的開發用法流程

關於jquery.fileupload結合PHP上傳圖片的開發用法流程

這陣子做了一個專案,涉及到了圖片上傳,以往用的都是uploadify這個外掛,感覺它在PC上的使用還是很強大的,

不過最近這個專案涉及到了移動端的上傳,其實uploadify也可以,但是他有一個 uploadify.swf,這個東東在移動端可是不被待見的,需要調整才可以.

我是懶得去調整uploadify,而且也不能保證調整之後會比原裝的更好,因此,採用了另一個外掛: jquery.fileupload,

本來也是想去網上搜羅一下這個外掛的具體用法,然後我就可以坐享其成了,

可現實結果告訴我你不要做夢了,趕緊自己研究吧.

對於一個需要解決實際問題的碼農來說,他最想要的是什麼?當然是可完成的邏輯了.

可網上都在講這個外掛的基本理論,試問,那邊有官網我用你講什麼理論呢?對不對.

先來看一下官網截圖吧:

我是喜歡它結合bootstrap的美觀性,所以用了它.

言歸正傳,首先做上傳圖片這個功能之前一定要明確這樣幾個步驟:

1.前端上傳頁面和控制元件.

2.後端可以接收處理的邏輯程式碼檔案(一般檔案只能以POST進行接收,雖然是廢話,但還是要強調.真的有遇到過用GET提交的.).

3.你還想幹嘛?那就誰也不知道了.

先來建立一個HTML頁面,取名為 addimage.html

需要引入的資原始檔如下(存放位置不是唯一的,這是我的專案資原始檔的存放結構)

<link type="text/css"
rel="stylesheet" href="/css/bootstrap.css" /> <script type="text/javascript" src="/js/jquery-1.11.1.min.js"></script> <link rel="stylesheet" type="text/css" href="/css/upload/jquery.fileupload.css" /> <script type="text/javascript" src="/js/upload/jquery.ui.widget.js"></script> <
script type="text/javascript" src="/js/upload/jquery.iframe-transport.js"></script> <script type="text/javascript" src="/js/upload/jquery.fileupload.js"></script>

然後在頁面中,新增一個input file型別的標籤程式碼:

<span class="btn btn-primary fileinput-button">
    <i class="glyphicon glyphicon-plus"></i>
    <span>請選擇上傳檔案</span>
    <input id="fileupload" type="file" name="files[]" multiple>
</span>

最後再新增一組,JS程式碼段,即可:

<script type="text/javascript">
    $("#fileupload").fileupload({
        url: "/street/api/upload_street_image", //後臺程式碼URL地址
        dataType: "json",                       //返回資料的型別
        sequentialUploads: false,               
        autoUpload: true,                       //是否允許自動上傳檔案.
        formData: { adbumnid: "{$streetid}" },  //引數
        //選擇新增檔案後,新增檔案前,所執行的方法.
        add: function (e, data) {               
            data.submit();//提交
        },
        //上傳後返回的引數處理邏輯.
        done: function (e, data) {
            var json = eval("(" + data.result + ")");
            //console.log(json);
            layer.msg(json.msg);
            if (json.code == 0) {
                //回撥父級載入資料方法.
                window.parent.vStreetAlbum.getPhotoList(1, 12);
            }
            
        }
    });
</script>

這樣一來前臺的頁面的新增就結束了.

再來新增後臺的接受檔案處理邏輯.

我的專案是PHP開發的,因此接下來這裡的程式碼只採用PHP程式碼為例項.

(PHP版本為7,這個很重要,因為PHP5的一些東西在7裡面已經被不建議了)

專案是TP5框架,所以需要在api介面中增加一個function,

/**
 * 獲取設定上傳檔案.
 * @author xingzhi 2018年9月4日
 * @param int 圖片所屬專輯主鍵id
 */
public function upload_street_image($adbumnid)

接下來在這個方法內寫自己需要實現的邏輯,首先需要判斷這個檔案是否存在吧?

//驗證上傳的檔案是否存在.
if(!$_FILES['files']['error']){
    $this->result['msg'] = '上傳檔案錯誤.';
    $this->result['code'] = -1;
} else { }

如果存在,那麼就需要把它相關的引數取出來

//圖片原始檔名稱.
$file_original_name = $_FILES['files']['name'][0];
//臨時圖片路徑
$temp_img = $_FILES['files']['tmp_name'][0];
//檔案型別.
$file_type = $_FILES['files']['type'][0];
//副檔名稱.
$file_existion = pathinfo($file_original_name, PATHINFO_EXTENSION);
//檔案大小
$file_size = $_FILES['files']['size'][0];

接下來需要獲取圖片的EXIF元資訊.

工作時有同僚曾問過我什麼是EXIF? what? 那就順便簡單科普一下,

個人的理解, EXIF其實就是是圖片中可交換的資料資訊和拍攝資料.例如,圖片寬高,圖片大小,拍攝日期,相機型號,曝光,IOS速度等這些拍攝資料.

它由日本電子發展工業協會在1996最初定製,還真的不要小看了日本的科技.當然EXIF還有很多很多引數,感興趣的可以自行研究.

下面是php來獲取EXIF資料資訊的邏輯,如果你的程式無法識別 exif_read_data 這個方法,那請先去研究一下PHP.INI的配置吧.

//EXIF 元資訊. 預設為false.
$exif = false;
//如果是 jpg的 則讀取.否則不讀取.
if($file_type == "image/jpeg"){
    //獲取圖片的exif資訊.
    $exif = exif_read_data($temp_img,"IFD0");
}

然後是獲取必要的引數

//獲取時間.
if(empty($exif["DateTimeOriginal"])){
    $DateTimeOriginal = date('Y-m-d H:i:s.u', time());
} else {
    //DateTimeOriginal 的時間日期部分的引數是 2018:08:08 08:08:08 這個樣子,所以需要處理一下才能入庫
    $DateTimeOriginal = str_replace(':', '-', substr($exif["DateTimeOriginal"], 0, 10)).substr($exif["DateTimeOriginal"], 10);
}
$Make = $exif["Make"];                            //製造廠商.
$Model = $exif["Model"];                        //相機型號
$ExposureTime = $exif['ExposureTime'];            //曝光時間
$ExifVersion = $exif['ExifVersion'];            //EXIF 版本.
$ISOSpeedRatings = $exif['ISOSpeedRatings'];    //ISO 速度.

接下來就是保證你要儲存的檔案物理路徑是要存在的才行,因此要判斷\要判斷\要判斷.重要的事情說三次.

//圖片儲存物理根路徑.
$save_root_path = Config::get("PHOTOS_SAVE_ROOT");
//耳二級目錄
$save_sub_dir = Config::get("SECOND_DIR_PATH")['STREET'];
//縮圖片儲存目錄物理根路徑.
$save_t_dir_path = "/thumbnail";
//原始圖片儲存目錄物理根路徑.
$save_o_dir_path = "/".date('Ym', strtotime($DateTimeOriginal))."/";
//檔名稱.
$filename = date('Ymdhis')."_".create_guid().".".$file_existion;
//驗證略圖目錄
if(!is_dir($save_root_path.$save_sub_dir.$save_t_dir_path.$save_o_dir_path)){
    mkdir($save_root_path.$save_sub_dir.$save_t_dir_path.$save_o_dir_path, 0777, true);
}
//驗證原始目錄
if(!is_dir($save_root_path.$save_sub_dir.$save_o_dir_path)){
    mkdir($save_root_path.$save_sub_dir.$save_o_dir_path, 0777, true);
}

這樣一來,原始圖片獲取到了,引數也整理完了,路徑也驗證通過了,那就要實現核心部分的落庫和裁圖了.

資料庫落庫程式碼就不列舉了,每個業務不同,程式碼也都一樣,沒什麼好說的.

PHP要處理圖片,就避免不了需要 gd庫了,怎麼辦?開啟PHP.INI檔案,自行學習吧,這裡不闊論.

首先一定要呼叫TP的Image類.先來引入它,

use think\Image;

然後呼叫它

//例項化圖片操作類
$image = Image::open($temp_img);
$image->open($temp_img);

最後移動和裁切它就可以了

//移動儲存原始圖
if(move_uploaded_file($temp_img, $save_root_path.$save_sub_dir.$save_o_dir_path.$filename)){
    //儲存縮圖
    $image->thumb(
    Config::get("STREET_THUB_WIDTH"),
    Config::get("STREET_THUB_HEIGHT"),
    Image::THUMB_CENTER)->
    save($save_root_path.$save_sub_dir.$save_t_dir_path.$save_o_dir_path.$filename);
    $dba = new Streetphoto();
    $dba->set_street_imagecount($adbumnid);
    $this->result['msg'] = "上傳成功.";
    $this->result['data'] = array(
        'dbval' => $value,
        't' => Config::get("IMAGE_DOMAIN_URL").$save_sub_dir.$save_t_dir_path.$save_o_dir_path.$filename,
        'o' => Config::get("IMAGE_DOMAIN_URL").$save_sub_dir.$save_o_dir_path.$filename,
    );
} else {
    $this->result['msg'] = "上傳失敗.";
    $this->result['code'] = -1;
}

最後返回結果,因為前端需要的是json資料,那就返回json資料

return json_encode($this->result);

到此上傳圖片資料的過程就完事兒了.