<?php
class?FileUpload{
????private?$datainfo;//上傳文件的數(shù)據(jù)信息
????private?$allow_size;//允許上傳文件的大小
????private?$allow_type;//允許類型數(shù)組
????private?$temp_fileExt;//上傳文件擴(kuò)展名
????private?$file_category;//上傳文件的種類
????private?$rootPath;//存放的根路徑
????private?$destination;//文件最終存放的全路徑
????
????public?function?__construct($name,$allow_size,$allow_type,$rootPath="./upload/"){
????????//檢測(cè)服務(wù)器$_FILES中是否有上傳數(shù)據(jù)
????????if(!$this->is_uploadfile_exists($name)){
????????????exit("客戶端文件未上傳至服務(wù)端,請(qǐng)檢查表單提交方式是否為post并且encotype的字符串是否正確,還有input的name名字是否正確等phpini的配置!");
????????}
????????$this->init($name,$allow_size,$allow_type,$rootPath);
????????//檢查臨時(shí)文件是否是通過Post方式上傳的
????????if(!$this->is_httpPost_upload()){
????????????exit("上傳的文件不是通過Http的Post方式上傳的,Game?Over!");
????????}
????????//檢查客戶端上傳文件至服務(wù)端是否有錯(cuò)誤
????????if($this->checkError()){
????????????$this->showErrorMessage();
????????}
????????//檢查上傳的文件大小
????????if($this->checkSize()){
????????????exit("上傳文件失敗!?上傳文件大小超出允許范圍");
????????}
????????$this->setTempFileExt();
????????//檢查上傳的文件類型是否符合要求
????????if(!$this->checkFileType()){
????????????exit("上傳文件失敗!?文件類型不符合");
????????}
????????//如果文件是圖片類型,檢測(cè)其是不是真實(shí)的圖片
????????if($this->file_category=="image"){
????????????$result=$this->is_realPic();
????????????if($result===false){
????????????????exit("上傳文件失敗!?該文件不是一個(gè)真實(shí)的圖片文件,Game?Over");
????????????}
????????}
????????//移動(dòng)文件參數(shù)初始化
????????$this->move_params_init();
????}
????public?function?file_move(){
????????//移動(dòng)文件是否成功
????????$result=move_uploaded_file($this->datainfo["tmp_name"],$this->destination);
????????if($result===false){
????????????exit("文件上傳失敗!在移動(dòng)臨時(shí)文件至最終目錄下失敗");
????????}
????????else{
????????????echo?"文件上傳成功!";
????????}
????}
????/*
????*????@function?檢測(cè)文件是否由客戶端上傳至服務(wù)端
????*????@return?boolean?返回true表示已經(jīng)上傳到了,false表示沒有上傳到
????*/
????public?function?is_uploadfile_exists($name){
????????if(isset($_FILES[$name])){
????????????return?true;
????????}
????????else{
????????????return?false;
????????}
????}
????
????/*
????*????@function?初始化上傳文件參數(shù)?
????*/
????public?function?init($name,$allow_size,$allow_type,$rootPath){
????????$this->datainfo=$_FILES[$name];
????????$this->allow_size=$allow_size;
????????$this->allow_type=$allow_type;
????????$this->rootPath=$rootPath;
????}
????
????/*
????*????@function?是否httpPost方式上傳的
????*????@return?boolean?返回true表示是,false表示否
????*/
????public?function?is_httpPost_upload(){
????????if(is_uploaded_file($this->datainfo["tmp_name"])){
????????????return?true;
????????}
????????else{
????????????return?false;
????????}
????}
????
????/*
????*????@function?上傳是否有錯(cuò)
????*????@return?boolean?返回true表示有錯(cuò)誤,false表示無錯(cuò)誤
????*/
????public?function?checkError(){
????????if($this->datainfo["error"]==0){
????????????return?false;
????????}
????????else{
????????????return?true;
????????}
????}
????
????/*
????*????@function?顯示錯(cuò)誤信息并退出
????*????@return?none
????*/
????public?function?showErrorMessageExit(){
????????$err=$this->datainfo["error"];
????????$errMessage="";
????????switch($err){
????????????case?1:
????????????????$errMessage="上傳的文件超過了php.ini中upload_max_filesize選項(xiàng)限制的值";
????????????????break;
????????????case?2:
????????????????$errMessage="上傳文件的大小超過了HTML表單中MAX_FILE_SIZE選項(xiàng)指定的值";
????????????????break;
????????????case?3:
????????????????$errMessage="文件只有部分被上傳";
????????????????break;
????????????case?4:
????????????????$errMessage="沒有文件被上傳";
????????????????break;
????????????case?6:
????????????????$errMessage="找不到臨時(shí)文件夾";
????????????????break;
????????????case?7:
????????????????$errMessage="文件寫入失敗";
????????????????break;
????????????default:
????????????????$errMessage="系統(tǒng)錯(cuò)誤";
????????????????break;
????????}
????????exit("文件上傳失敗!?".$errMessage);
????}
????
????/*
????*????@function?文件大小是否超出允許值
????*????@return?boolean?返回true表示超過允許大小,false表示沒有超出允許大小
????*/
????public?function?checkSize(){
????????if($this->allow_size<$this->datainfo["size"]){
????????????return?true;
????????}
????????else{
????????????return?false;
????????}
????}
????/*
????*????@function?設(shè)定服務(wù)器臨時(shí)文件的真正文件類型
????*/
????public?function?setTempFileExt(){
????????/*?最笨的辦法,遇到串改type就徹底完蛋
????????$this->temp_fileExt=$this->datainfo["type"];
????????*/
????????//粗糙的處理方式,遇到xx.xx.jpg等特殊命名的文件名就直接完蛋
????????$this->temp_fileExt=pathinfo($this->datainfo["name"],PATHINFO_EXTENSION);
????????
????????/*?因?yàn)閜hp版本低于5.3?finfo_open無法使用
????????$ext=$this->getFileExt();
????????$this->temp_fileExt=$ext;
????????*/
????}????
????
????/*
????*????@function?獲取文件后類型名
????*????@param?none
????*????@return?string文件類型名
????*????@notice?先通過內(nèi)部匹配獲得文件類型,如果無法匹配就只能截取出頭文件轉(zhuǎn)十六進(jìn)制進(jìn)行類型碼匹配了
????*/
????public?function?getFileExt(){
????????$file=$this->datainfo["tmp_name"];
????????$finfo=finfo_open(FILEINFO_MIME);//finfo過程化的使用return?a?mini?type且只有在php5.3以上
????????if(!finfo){
????????????//針對(duì)獲取不到mini?type的情況的補(bǔ)救,打開文件截取4個(gè)字節(jié)
????????????$res=fopen($file,"rb");
????????????$bin=fread($res,4);
????????????fclose($res);
????????????$arr=unpack("c4chars",$bin);
????????????//dechex()?函數(shù)把十進(jìn)制轉(zhuǎn)換為十六進(jìn)制
????????????$code=dechex($arr["chars1"]).dechex($arr["chars2"]).dechex($arr["chars3"]).dechex($arr["chars4"]);//組成16進(jìn)制數(shù)
????????????$ext=$this->getFileTypeByC4chars_TypeCode($code);//根據(jù)類型碼查找硬編碼值查表
????????}
????????else{
????????????$ext=finfo_file(finfo,$file);
????????}
????????finfo_close($finfo);//關(guān)閉資源
????????return?$ext;
????}
????//太長了發(fā)布不了接下面