반응형
본 글에서는 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;
}
}
반응형
'개발 꿀팁 > PHP' 카테고리의 다른 글
php 조작 redis의 상용 방법은 어떤 것이 있습니까?php조작레디스방법정리(코드첨부) (0) | 2022.07.26 |
---|---|
php와 ajax는 어떻게 표의 실시간 편집이 가능합니까(코드 첨부) (0) | 2022.07.25 |
php 구현은 혼합 인증 코드와 이미지 인증 코드를 생성하고 테스트한다(코드) (0) | 2022.07.25 |
TP5 프레임워크에서 재귀적 무한 등급 구현 방법 (0) | 2022.07.25 |
thinkphp5에서 문자열을 가로채는 방법에는 어떤 것들이 있나요?(두 가지 방법으로 실현) (0) | 2022.07.25 |