개발 꿀팁/PHP

Thinkphp 업로드 클래스 이미지 업로드를 위한 코드

Jammie 2022. 7. 25. 16:53
반응형

본 글에서는 Thinkphp 업로드 클래스에 이미지 업로드가 가능한 코드로 참고가 되므로 도움이 되시기 바랍니다.
씽크핑은 어떻게 사진을 올립니까?자, 이제 좀 더 자세히 소개해드릴게요!

1. 패키지 업로드 방법

<?php

//불러오기 업로드

public function uploadUser(){

   $banner=$this->uploadYmdImg('ymd_banner');

   if(!empty($banner)){

      $data['ymd_banner']=$banner;

   }

}

   /*

 *사진을 봉인하여 업로드하다

 * */  

public function uploadYmdImg($fileName,$route="banner"){

    if(!empty($_FILES[$fileName]['tmp_name'])){

            $upload = new \Think\Upload();//인스턴스화 업로드 클래스

            $upload->maxSize   =     3145728 ;// 첨부 파일 업로드 크기 설정

            $upload->exts      =     array('jpg', 'gif', 'png', 'jpeg');//첨부 파일 업로드 형식 설정

            $upload->rootPath  =      './Upload/'.$route.'/'; //첨부 파일 업로드 루트 설정

            // 개별 파일 업로드

            $info   =   $upload->uploadOne($_FILES[$fileName]);

            if(!$info) {// 오류 메시지 업로드 중 오류

                $this->error($upload->getError());

            }else{// 업로드 파일 정보 가져오기

                return C('TMPL_PARSE_STRING.__YIMUDI__').'/Upload/'.$route.'/'.$info['savepath'].$info['savename'];

           }            

    }else{

        return NULL;

    }       

}

2, Thinkphp 내부 정의 업로드 클래스

<?php

// +----------------------------------------------------------------------

// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]

// +----------------------------------------------------------------------

// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.

// +----------------------------------------------------------------------

namespace Think;

class Upload {

    /**

     *기본 업로드 설정

     * @var array

     */

    private $config = array(

        'mimes'         =>  array(), //업로드 허용 파일MiMe 형식

        'maxSize'       =>  0, //업로드된 파일 크기 제한 (0- 제한 없음)

        'exts'          =>  array(), //업로드 허용 파일 접미사

        'autoSub'       =>  true, //자동 하위 디렉터리 저장 파일

        'subName'       =>  array('date', 'Y-m-d'), //하위 디렉터리 생성 방법, [0] - 함수 이름, [1] - 매개 변수, 다중 매개 변수 사용 배열

        'rootPath'      =>  './Uploads/', //루트 경로 저장

        'savePath'      =>  '', //경로 저장

        'saveName'      =>  array('uniqid', ''), //파일 이름 지정 규칙, [0] - 함수 이름, [1] - 매개 변수 업로드, 다중 매개 변수 배열 사용

        'saveExt'       =>  '', //파일 저장 접미사, 빈칸은 원래대로 사용

        'replace'       =>  false, //같은 이름의 존재 덮어쓰기

        'hash'          =>  true, //해시 인코딩 생성 여부

        'callback'      =>  false, //파일 정보 배열을 반환할 때 파일에 콜백이 있는지 감지

        'driver'        =>  '', // 파일 업로드 드라이브

        'driverConfig'  =>  array(), // 드라이브 설정 업로드

    );

 

    /**

     * 오류 메시지 업로드

     * @var string

     */

    private $error = ''; //오류 메시지 업로드

 

    /**

     * 드라이브 인스턴스 업로드

     * @var Object

     */

    private $uploader;

 

    /**

     * 업로드 인스턴스를 만드는 방법

     * @param array  $config배치하다

     * @param string $driver 사용할 업로드 드라이버 LOCAL-로컬 업로드 드라이버, FTP-FTP 업로드 드라이버

     */

    public function __construct($config = array(), $driver = '', $driverConfig = null){

        /* 설정 가져오기 */

        $this->config   =   array_merge($this->config, $config);

 

        /* 업로드 드라이브 설정 */

        $this->setDriver($driver, $driverConfig);

 

        /* 문자열 설정 매개 변수를 배열로 변환하기 위한 설정 조정 */

        if(!empty($this->config['mimes'])){

            if(is_string($this->mimes)) {

                $this->config['mimes'] = explode(',', $this->mimes);

            }

            $this->config['mimes'] = array_map('strtolower', $this->mimes);

        }

        if(!empty($this->config['exts'])){

            if (is_string($this->exts)){

                $this->config['exts'] = explode(',', $this->exts);

            }

            $this->config['exts'] = array_map('strtolower', $this->exts);

        }

    }

 

    /**

     * $this->name을( 를) 사용하여 설정 가져오기

     * @param  string $name 설정 이름

     * @return multitype    설정값

     */

    public function __get($name) {

        return $this->config[$name];

    }

 

    public function __set($name,$value){

        if(isset($this->config[$name])) {

            $this->config[$name] = $value;

            if($name == 'driverConfig'){

                //드라이브 설정 변경 후 업로드 드라이브 재설정

                //참고: 드라이브 설정을 변경하려면 드라이브를 선택해야 합니다

                $this->setDriver(); 

            }

        }

    }

 

    public function __isset($name){

        return isset($this->config[$name]);

    }

 

    /**

     *마지막 업로드 오류 정보 가져오기

     * @return string오류 메시지

     */

    public function getError(){

        return $this->error;

    }

 

    /**

     * 개별 파일 업로드件

     * @param  array  $file 파일 배열

     * @return array        성공적으로 업로드된 파일 정보

     */

    public function uploadOne($file){

        $info = $this->upload(array($file));

        return $info ? $info[0] : $info;

    }

 

    /**

     * 파일 업로드

     * @param 파일 정보 배열 $files,보통 $_FILES 배열

     */

    public function upload($files='') {

        if('' === $files){

            $files  =   $_FILES;

        }

        if(empty($files)){

            $this->error = '업로드되지 않은 파일!';

            return false;

        }

 

        /*업로드 루트 탐지 */

        if(!$this->uploader->checkRootPath($this->rootPath)){

            $this->error = $this->uploader->getError();

            return false;

        }

 

        /*업로드된 디렉터리 검사 */

        if(!$this->uploader->checkSavePath($this->savePath)){

            $this->error = $this->uploader->getError();

            return false;

        }

 

        /* 파일 하나씩 검색하여 업로드하기 */

        $info    =  array();

        if(function_exists('finfo_open')){

            $finfo   =  finfo_open ( FILEINFO_MIME_TYPE );

        }

        //업로드 파일 배열 정보 처리

        $files   =  $this->dealFiles($files);    

        foreach ($files as $key => $file) {

            $file['name']  = strip_tags($file['name']);

            if(!isset($file['key']))   $file['key']    =   $key;

            /* 파일 형식을 확장하여 FLASH 업로드 $FILES 배열에서 반환되는 파일 형식 오류 해결 */

            if(isset($finfo)){

                $file['type']   =   finfo_file ( $finfo ,  $file['tmp_name'] );

            }

 

            /* 파일 업로드 접미사를 가져옵니다. 접미사가 없는 파일 업로드 허용 */

            $file['ext']    =   pathinfo($file['name'], PATHINFO_EXTENSION);

 

            /* 파일 업로드 검사*/

            if (!$this->check($file)){

                continue;

            }

 

            /* 파일 hash 가져오기 */

            if($this->hash){

                $file['md5']  = md5_file($file['tmp_name']);

                $file['sha1'] = sha1_file($file['tmp_name']);

            }

 

            /* 콜백 함수를 호출하여 파일이 있는지 여부를 검사합니다 */

            $data = call_user_func($this->callback, $file);

            if( $this->callback && $data ){

                if ( file_exists('.'.$data['path'])  ) {

                    $info[$key] = $data;

                    continue;

                }elseif($this->removeTrash){

                    call_user_func($this->removeTrash,$data);//휴지통 삭제

                }

            }

 

            /* 저장 파일 이름 생성 */

            $savename = $this->getSaveName($file);

            if(false == $savename){

                continue;

            } else {

                $file['savename'] = $savename;

            }

 

            /* 하위 디렉터리 검색 및 만들기 */

            $subpath = $this->getSubPath($file['name']);

            if(false === $subpath){

                continue;

            } else {

                $file['savepath'] = $this->savePath . $subpath;

            }

 

            /* 이미지 파일을 엄격하게 검사하다 */

            $ext = strtolower($file['ext']);

            if(in_array($ext, array('gif','jpg','jpeg','bmp','png','swf'))) {

                $imginfo = getimagesize($file['tmp_name']);

                if(empty($imginfo) || ($ext == 'gif' && empty($imginfo['bits']))){

                    $this->error = '잘못된 그림 파일!';

                    continue;

                }

            }

 

            /* 파일 저장 및 성공적인 파일 기록하기 */

            if ($this->uploader->save($file,$this->replace)) {

                unset($file['error'], $file['tmp_name']);

                $info[$key] = $file;

            } else {

                $this->error = $this->uploader->getError();

            }

        }

        if(isset($finfo)){

            finfo_close($finfo);

        }

        return empty($info) ? false : $info;

    }

 

    /**

     * 업로드 파일 배열 변수를 올바른 방식으로 변환

     * @access private

     * @param array $files  업로드된 파일 변수

     * @return array

     */

    private function dealFiles($files) {

        $fileArray  = array();

        $n          = 0;

        foreach ($files as $key=>$file){

            if(is_array($file['name'])) {

                $keys       =   array_keys($file);

                $count      =   count($file['name']);

                for ($i=0; $i<$count; $i++) {

                    $fileArray[$n]['key'] = $key;

                    foreach ($keys as $_key){

                        $fileArray[$n][$_key] = $file[$_key][$i];

                    }

                    $n++;

                }

            }else{

               $fileArray = $files;

               break;

            }

        }

       return $fileArray;

    }

 

    /**

     * 업로드 드라이브 설정

     * @param string $driver 드라이브 이름

     * @param array $config 드라이브 설정     

     */

    private function setDriver($driver = null, $config = null){

        $driver = $driver ? : ($this->driver       ? : C('FILE_UPLOAD_TYPE'));

        $config = $config ? : ($this->driverConfig ? : C('UPLOAD_TYPE_CONFIG'));

        $class = strpos($driver,'\\')? $driver : 'Think\\Upload\\Driver\\'.ucfirst(strtolower($driver));

        $this->uploader = new $class($config);

        if(!$this->uploader){

            E("업로드 드라이버가 없습니다:{$name}");

        }

    }

 

    /**

     *업로드한 파일 검사

     * @param array $file 파일 정보

     */

    private function check($file) {

        /* 파일 업로드 실패, 오류 코드 캡처*/

        if ($file['error']) {

            $this->error($file['error']);

            return false;

        }

 

        /*잘못된 업로드 */

        if (empty($file['name'])){

            $this->error = '알 수 없는 업로드 오류!';

        }

 

        /*합법적인 업로드 여부를 검사하다 */

        if (!is_uploaded_file($file['tmp_name'])) {

            $this->error = '파일 불법 업로드!';

            return false;

        }

 

        /* 파일 크기 검사 */

        if (!$this->checkSize($file['size'])) {

            $this->error = '업로드 파일 크기가 맞지 않음!';

            return false;

        }

 

        /* 서류를 검사하다Mime유형*/

        //TODO:FLASH업로드한 파일의 mime 형식은 다음과 같습니다application/octet-stream

        if (!$this->checkMime($file['type'])) {

            $this->error = '업로드 파일 MIME 형식 허용 안 함!';

            return false;

        }

 

        /* 파일 접미사 검사 */

        if (!$this->checkExt($file['ext'])) {

            $this->error = '파일 접미사를 업로드할 수 없음';

            return false;

        }

 

        /*검측을 통과하다 */

        return true;

    }

 

 

    /**

     * 오류 코드 정보 가져오기

     * @param string $errorNo  오류 번호

     */

    private function error($errorNo) {

        switch ($errorNo) {

            case 1:

                $this->error = '업로드한 파일이 초과되었습니다 php.ini 중 upload_max_filesize 옵션 제한 값!';

                break;

            case 2:

                $this->error = '업로드 파일의 크기가 초과되었습니다 HTML MAX_FILE_SIZE 폼에서 지정한 값!';

                break;

            case 3:

                $this->error = '파일 일부만 업로드됨!';

                break;

            case 4:

                $this->error = '업로드된 파일이 없습니다!';

                break;

            case 6:

                $this->error = '임시 폴더를 찾을 수 없음!';

                break;

            case 7:

                $this->error = '파일을 쓸 수 없음!';

                break;

            default:

                $this->error = '알 수 없는 업로드 오류!';

        }

    }

 

    /**

     * 파일 크기가 올바른지 검사합니다

     * @param integer $size 데이터

     */

    private function checkSize($size) {

        return !($size > $this->maxSize) || (0 == $this->maxSize);

    }

 

    /**

     *업로드한 파일의 MIME 형식이 올바른지 확인합니다

     * @param string $mime 데이터

     */

    private function checkMime($mime) {

        return empty($this->config['mimes']) ? true : in_array(strtolower($mime), $this->mimes);

    }

 

    /**

     * 업로드한 파일 접미사가 올바른지 검사합니다

     * @param string $ext접미사

     */

    private function checkExt($ext) {

        return empty($this->config['exts']) ? true : in_array(strtolower($ext), $this->exts);

    }

 

    /**

     *업로드 파일 이름 지정 규칙에 따라 저장 파일 이름 가져오기

     * @param string $file파일 정보

     */

    private function getSaveName($file) {

        $rule = $this->saveName;

        if (empty($rule)) { //파일 이름 그대로 유지

            /* pathinfo 중국어 파일 이름 BUG 해결 */

            $filename = substr(pathinfo("_{$file['name']}", PATHINFO_FILENAME), 1);

            $savename = $filename;

        } else {

            $savename = $this->getName($rule, $file['name']);

            if(empty($savename)){

                $this->error = '파일 이름 지정 규칙 오류!';

                return false;

            }

        }

 

        /* 파일 접미사 저장, 파일 접미사 강제 변경 지원 */

        $ext = empty($this->config['saveExt']) ? $file['ext'] : $this->saveExt;

 

        return $savename . '.' . $ext;

    }

 

    /**

     * 하위 디렉터리 이름 가져오기

     * @param array $file  업로드한 파일 정보

     */

    private function getSubPath($filename) {

        $subpath = '';

        $rule    = $this->subName;

        if ($this->autoSub && !empty($rule)) {

            $subpath = $this->getName($rule, $filename) . '/';

 

            if(!empty($subpath) && !$this->uploader->mkdir($this->savePath . $subpath)){

                $this->error = $this->uploader->getError();

                return false;

            }

        }

        return $subpath;

    }

 

    /**

     * 지정한 규칙에 따라 파일이나 디렉터리 이름 가져오기

     * @param  array  $rule   규칙

     * @param  string $filename 원본 파일 이름

     * @return string           파일 또는 디렉터리 이름

     */

    private function getName($rule, $filename){

        $name = '';

        if(is_array($rule)){ //배열 규칙

            $func     = $rule[0];

            $param    = (array)$rule[1];

            foreach ($param as &$value) {

               $value = str_replace('__FILE__', $filename, $value);

            }

            $name = call_user_func_array($func, $param);

        } elseif (is_string($rule)){ //문자열 규칙

            if(function_exists($rule)){

                $name = call_user_func($rule);

            } else {

                $name = $rule;

            }

        }

        return $name;

    }
}

 

반응형