1. 程式人生 > >laravel5.5--封裝公共上傳類

laravel5.5--封裝公共上傳類

<?php

namespace App\Unloading\Api\Controllers;

use Storage;
use Image;
use Illuminate\Http\Request;
use App\Ship\Controllers\ApiController;

/**********************************
 *  檔案上傳
 *  formData方式,支援單圖、多圖上傳
 *  base64方式, 只支援單檔案上傳
 *  method: POST
 *  action: upload
 * param: 引數說明
 *                  ①file_type      允許上傳的檔案字尾,string型別,用逗號隔開
 *                  ②width          縮放寬度
 *                  ③height         縮放高度
 *                  ④dirName        儲存資料夾名稱,預設
 *                  ⑤upload_type    上傳方式,預設formData,可以是base64
 **********************************/
class ImgController extends ApiController
{    
    private $allow_type = array('gif', 'jpg','jpeg', 'png', 'zip', 'rar', 'txt', 'doc', 'pdf');
    private $img_type = array('gif','jpg','jpeg','png');//圖片格式,用來區分是否是圖片上傳(!勿動!)
    private $pic_dir = 'images';          //預設圖片上傳目錄
    private $file_dir = 'files';          //預設檔案上傳目錄
    private $upload_max_size = 20971520;  //最大上傳檔案20兆
    private $upload_type = 'formData';    //預設上傳方式
    private $img_width = '';              //預設不限制圖片寬度
    private $img_height = '';             //預設不限制圖片高度
    private static $watermark = 'uploads/images/qrcode.png';  //水印圖片地址

    public function upload(Request $request)
    {
        $param = $request->all();
        //upload_type    上傳方式,預設formData,可以是base64
        if(isset($param['upload_type']) && !empty($param['upload_type'])){
            $this->upload_type = $param['upload_type'];
        }
        //根據傳參呼叫不同的上傳方式
        switch ($this->upload_type){
            case 'formData':
                $data = $this->formData($request);
            break;
            case 'base64':
                //只支援單圖上傳,key健必須為file
                $data = $this->base64($param);
            break;
        }
        return $data;

    }

    /**
     * formData上傳方式
     * @param $request
     * @return array
     */
    private function formData($request){
        $files = $request->allFiles();
        $param = $request->all();
        $path = array();
        foreach ($files as $k=>$v){
            $type = $v->getClientOriginalExtension();//獲取字尾
            $size = $v->getSize();			//檔案大小
            //驗證是否有檔案限制
            if(isset($param['file_type']) && !empty($param['file_type'])){
                $file_type = explode(',',$param['file_type']);
            }else{
                $file_type = $this->allow_type;
            }
            if(!in_array($type,$file_type)){
                return ['code'=>301,'msg'=>'不支援'.$type.'檔案'];
            }
            //驗證檔案大小
            if($size > $this->upload_max_size){
                return ['code'=>301,'msg'=>'上傳檔案超過最大限制'];
            }
            //根據檔案型別上傳
            if(in_array($type,$this->img_type)){
                $width = $param['width']??$this->img_width;
                $height = $param['height']??$this->img_height;
                $dirName = $param['dirName']??$this->pic_dir;
                $path[] = self::imgs($v,$width,$height,$dirName);
            }else{
                $dirName = $param['dirName']??$this->file_dir;
                $path[] = self::files($v,$dirName);
            }

        }

        return $path;
    }

    /**
     * @param $param
     * @return array 返回圖片地址及字尾
     */
    private function base64($param){

        $img = $param['file'];
        $img = str_replace(array('_', '-'), array('/', '+'), $img);
        $b64img = substr($img, 0, 100);
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $b64img, $matches)) {
            $type = $matches[2];
            //驗證是否有檔案限制
            if(isset($param['file_type']) && !empty($param['file_type'])){
                $file_type = explode(',',$param['file_type']);
            }else{
                $file_type = $this->allow_type;
            }
            if(!in_array($type,$file_type)){
                return ['code'=>301,'msg'=>'不支援'.$type.'檔案'];
            }
            $img = str_replace($matches[1], '', $img);
            $img = base64_decode($img);
            $randName = 'base64';
            //如果是圖片存到圖片資料夾中,否則存到檔案中,如果設定,則都存到設定的資料夾中
            if(in_array($type,$this->img_type)){
                $dirName = $param['dirName']??$this->pic_dir;
                $picture = true;
            }else{
                $dirName = $param['dirName']??$this->file_dir;
            }
            $path = self::getUploadPath($randName,$type,$dirName);
            file_put_contents($path, $img);
            //如果是圖片則可以生成縮圖
            if($picture){
                $width = $param['width']??$this->img_width;
                $height = $param['height']??$this->img_height;
                Image::make($path)->resize($width, $height)->save($path);//生成縮圖
            }
            $ary['path'] = $path;
            $ary['ext'] = $type;
            return $ary;
        }
    }


    /**
     * 上傳檔案
     * @return 已上傳檔案相關資訊
     */
    private static function files($request,$dirName)
    {
        $info = self::getFileInfo($request, $dirName);
        //上傳檔案
        if(!Storage::disk('public')->put($info['path'], file_get_contents($info['realPath']))){
            abort(201, '上傳失敗');
        }
        unset($info['file'], $info['realPath']);

        return $info;
    }

    /**
     * 上傳圖片
     * $request 圖片資訊
     * $width   需要縮放寬度
     * $height  需要縮放高度
     * @return 已上傳圖片相關資訊
     **/
    private static function imgs($request,$width,$height,$dirName)
    {
        $info = self::getFileInfo($request,$dirName);
        //給圖片新增水印功能
//        $img = Image::make($info['file'])->resize($width, $height)->insert(self::$watermark,'bottom-right',15,10);
//        $img->save($info['path']);

        //上傳圖片
        if(!Image::make($info['file'])->resize($width, $height)->save($info['path'])){
            abort(201, '上傳失敗');
        }
        unset($info['file'], $info['realPath']);

        return $info;

    }

    /**
     * 隨機的檔名
     * @param int $len 隨機檔名的長度
     * @return str 隨機字串
     */
    private static function randName($name)
    {
        return md5(uniqid($name));
    }

    /**
     * 建立檔案上傳檔案到的路徑
     * @return str 檔案上傳的路徑
     */
    private static function createDir($dirName)
    {
        $dir = env('UPLOADPATH_FILE') . $dirName. '/'.  date('Ymd', time());
        if (is_dir($dir) || mkdir($dir, 0777, true)) {
            return $dir;
        }
    }

    /**
     * 獲取上傳檔案的路徑
     * @return str 檔案的全路徑
     */
    private static function getUploadPath($originalName, $ext = 'jpg', $dirName)
    {
        return self::createDir($dirName) . '/' . self::randName($originalName) . '.' . $ext;
    }

    /**
     * 生成上傳檔案相關資訊
     * @return 上傳檔案相關資訊
     **/
    private static function getFileInfo($file, $dirName)
    {
        // 檔案是否上傳成功
        if ($file->isValid()) {
            // 獲取檔案相關資訊
            $originalName = $file->getClientOriginalName(); // 檔案原名
            $ext = $file->getClientOriginalExtension();     // 副檔名
            $realPath = $file->getRealPath();   //臨時檔案的絕對路徑
            $type = $file->getClientMimeType();     //檔案型別
            $size = $file->getSize();			//檔案大小
            $path = self::getUploadPath($originalName, $ext, $dirName);//獲取儲存的檔案路徑

            return compact('file', 'path', 'ext', 'type', 'size', 'realPath' ,'originalName');
        }

        return ['code'=>301,'msg'=>'圖片上傳失敗,請重試'];
    }

}

相關推薦

laravel5.5--封裝公共

<?php namespace App\Unloading\Api\Controllers; use Storage; use Image; use Illuminate\Http\Request; use App\Ship\Controllers\ApiContr

封裝原生的檔案

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html

Android volley(5)MultipartEntity 封裝 volley —— 一個引數多張圖、多張圖片多張圖

一、前言 Google自從2013的IO大會上釋出volley框架之後就受到廣泛應用,的確,用過幾個網路請求庫,感覺volley還是很好用的,用起來也特別方便順手。但是遇到上傳檔案就比較麻煩,尤

【轉】HTML5的 input:file型控制

ati err format spa asi 拖拽 pdf 按鈕 shee 一、input:file屬性 屬性值有以下幾個比較常用: accept:表示可以選擇的文件MIME類型,多個MIME類型用英文逗號分開,常用的MIME類型見下表。 multiple:是否可以選擇多個

自己封裝framworks到應用商店報錯

script uil iss strong find lac targe 內容 link 參考鏈接: http://www.jianshu.com/p/60ac3ded34a0 http://ikennd.ac/blog/2015/02/stripping-unwanted

HTML5的 input:file型控制

name script pdf ava format openxml doc all reads 屬性值有以下幾個比較常用: accept:表示可以選擇的文件MIME類型,多個MIME類型用英文逗號分開,常用的MIME類型見下表。 multiple:是否可以選擇多個文件,多

php實現常用文件

ring item exe bre tex class 允許 excel aud 1 <?php 2 /** 3 * 上傳文件類 4 * @param _path : 服務器文件存放路徑 5 * @param _allowType : 允許

搜藏一個php文件

cti fault bre 單元素 出錯 構造 php文件 tmp log <?php /** * 上傳文件類 * @param _path : 服務器文件存放路徑 * @param _allowType : 允許上傳的文件類型和所對應的MIME * @pa

往VCSA6.5系統裏文件。

vcsa 上傳 默認情況下,VCSA6.5使用的是CSHELL,無法通過SFTP工具上傳和下載文件,需要將默認的CSHELL改成BASH SHELL即可。1、用root用戶登錄VCSA6.5命令行界面。2、在command命令界面輸入shell3、輸入命令chsh -s /bin/bash root

php圖片(支持縮放、裁剪、圖片縮略功能)

php圖片上傳類(支持縮放、裁剪、圖片縮代碼: /** * @author [Lee] <[<[email protected]>]> * 1、自動驗證文件是表單提交的文件還是base64流提交的文件 * 2、驗證圖片類型是否合法 * 3、驗證圖片尺寸是否合法 * 4、驗證圖片大小是否合法

input file實現多選,限制文件型,圖片前預覽功能

ava eight tag HA ont accep 多選 red 異常 限制上傳類型 & 多選:① accept 屬性只能與 <input type="file" /> 配合使用。它規定能夠通過文件上傳進行提交的文件類型。 ② multiple 屬性規

Laravel 5 - 文件

gin oot 存儲空間 alt pub ems mit part 方便 一、簡介 Laravel 有很棒的文件系統抽象層,是基於 Frank de Jonge 的 Flysystem 擴展包。 Laravel 集成的 Flysystem 提供了簡單的接口,可以操作本地端空

PHP文件

pre vat 創建失敗 cto code 文件上傳類 ech ext turn class Upload{ //錯誤信息 private $errorNo; private $errorMsg; //文件類型 private $e

spring-boot-1.5.15.RELEASE檔案大小限制

背景 有一個上傳檔案介面,在其他專案執行正常 @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file, @RequestParam("orgId") I

vue 封裝元件img

var _uploadTemplate = '<div>'+ '<input type="file" name="file" v-on:change="change" id="file" accept="img.png" style="display: none;">'

簡單封裝一個外掛——支援拖拽和預覽

最近碰到一個需求。需要上傳很多圖片,但是又不是批量上傳。場景是這樣的。我需要從資料表中查出一行一行的資料,每一行都需要更新一個對應的圖片。天才需求方不喜歡批量上傳,因為需要讓他們給每個圖片命名。 原生input flie上傳能滿足對方需求,但是不能方便拖拽和預

centos6.5 ftp檔案遇到的問題彙總

1、ftp 192.168.1.* -bash: ftp: command not found 解決方案:ftp命令沒有安裝  # yum install ftp 2、ftp: connect: 拒絕連線     解決方案:     (1

spring boot 學習筆記 (5) 檔案

一、配置  新增依賴包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</

SecureCRT 6.5從本地檔案到linux虛擬機器

前提:你的電腦已經安裝虛擬機器,我安裝的是VMware;並且在你的虛擬機器上面已經安裝linux,我安裝的是CentOS,建議安裝CentOS或者 Red Hat,尤其是紅帽,你遇到問題,在網上可以很快查到解決方法; 1,配置SecureCRT:選項-->會話選項--

在Vue中封裝一個檔案元件

封裝一個上傳檔案的元件,如下: 使用<input type='file'> 來實現檔案上傳,具體操作參照以往JS版的實現 這裡主要說作為一個元件,選中檔案之後,在輸入框中顯示檔名稱,點選Submit將將檔案傳給父元件,再由父元件提價到後臺