<?php
namespace app\extensions\upload;

class Uploader {
//类开始
	public $max_size	= 2048000;	//设置上传文件大小
	public $file_name	= 'date';	//重命名方式代表以时间命名，其他则使用给予的名称
	public $allow_types = '*';			//允许上传的文件扩展名，不同文件类型用“|”隔开，*表示无限制
	public $errmsg		= '';		//错误信息
	public $uploaded	= '';		//上传后的文件名(包括文件路径)
	public $save_path;				//上传文件保存路径
	private $files;					//提交的等待上传文件
	private $file_type	= array();	//文件类型
	private $ext		= '';		//上传文件扩展名
	
	/**
	* 构造函数，初始化类
	* @access public
	* @param string $file_name 上传后的文件名
	* @param string $save_path 上传的目标文件夹
	*/
	public function __construct($save_path = './upload/',$file_name = 'date') {
		$this->file_name   = $file_name;//重命名方式代表以时间命名，其他则使用给予的名称
		$this->save_path   = $save_path;
	}
	
	/**
	* 上传文件
	* @access public
	* @param $files 等待上传的文件(表单传来的$_FILES[])
	* @return boolean 返回布尔值
	*/
	public function upload_file($files) {
		$name = $files['name'];
		$type = $files['type'];
		$size = $files['size'];
		$tmp_name = $files['tmp_name'];
		$error = $files['error'];
		
		switch ($error) {
			case 0 : 
			$this->errmsg = '';
			break;
			case 1 : 
			$this->errmsg = '超过了php.ini中文件大小';
			break;
			case 2 : 
			$this->errmsg = '超过了MAX_FILE_SIZE 选项指定的文件大小';
			break;
			case 3 : 
			$this->errmsg = '文件只有部分被上传';
			break;
			case 4 : 
			$this->errmsg = '没有文件被上传';
			break;
			case 5 : 
			$this->errmsg = '上传文件大小为0';
			break;
			default : 
			$this->errmsg = '上传文件失败！';
			break;
		}
		if($error == 0 && is_uploaded_file($tmp_name)) {
			//检测文件类型
			if($this->check_file_type($name) == false){
				return false;
			}
			//检测文件大小
			if($size > $this->max_size){
				$this->errmsg = '上传文件'.$name.'太大，最大支持'.ceil($this->max_size/1024).'KB的文件';
				return false;
			}
			$this->set_save_path();//设置文件存放路径
			if($this->file_name=="date"){//设置新文件名
				$new_name = date('YmdHis').'_'.rand(10000, 99999).'.'.$this->ext;
			}elseif($this->file_name=="md5"){
				$new_name = md5(date('YmdHis').'_'.rand(10000, 99999)).'.'.$this->ext;
			}else{
				$new_name = $this->file_name.'.'.$this->ext;
			}
			$this->uploaded = $this->save_path.$new_name;//上传后的文件名
			//移动文件
			if(move_uploaded_file($tmp_name,$this->uploaded)){
				$filesize = filesize($this->uploaded);
				if($filesize<10240000){ //小于10MB的文件检测是否含有非法脚本
					$fcontent = file_get_contents($this->uploaded);
					if(stripos($fcontent, '<?php')!==false){
						unlink($this->uploaded);
						$this->errmsg = '文件含有非法脚本！';
						return false;
					}
				}
				$this->errmsg = '';
				return true;
			}else{
				$this->errmsg = '文件'.$this->uploaded.'上传失败！';
				return false;
			}
		
		}
	}
	
	/**
	* 检查上传文件类型
	* @access public
	* @param string $filename 等待检查的文件名
	* @return 如果检查通过返回true 未通过则返回false和错误消息
	*/
	public function check_file_type($filename){
		$ext = $this->get_file_type($filename);
		$this->ext = $ext;
		if($this->allow_types=="*"){
			return true;
		}
		$allow_types = explode('|',$this->allow_types);//分割允许上传的文件扩展名为数组
		//echo $ext;
		//检查上传文件扩展名是否在请允许上传的文件扩展名中
		if(in_array($ext,$allow_types)){
			return true;
		}else{
			//$this->errmsg = '上传文件'.$filename.'类型错误，只支持上传'.str_replace('|',',',$this->allow_types).' 等文件类型!';
			$this->errmsg = '上传文件'.$filename.'类型错误!';
			return false;
		}
	}
	
	/**
	* 取得文件类型
	* @access public
	* @param string $filename 要取得文件类型的目标文件名
	* @return string 文件类型
	*/
	public function get_file_type($filename){
		$info = pathinfo($filename);
		$ext = $info['extension'];
		$ext = strtolower($ext);
		return $ext;
	}
	
	/**
	* 设置文件上传后的保存路径
	*/
	public function set_save_path(){
		//$this->save_path = (preg_match('//$/',$this->save_path)) ? $this->save_path : $this->save_path . '/';
		if(!is_dir($this->save_path)){
			//如果目录不存在，创建目录
			$this->set_dir();
		}
	}
	
	
	/**
	* 创建目录
	* @access public
	* @param string $dir 要创建目录的路径
	* @return boolean 失败时返回错误消息和false
	*/
	public function set_dir($dir = null){
		//检查路径是否存在
		if(!$dir){
			$dir = $this->save_path;
		}
		if(is_dir($dir)){
			$this->errmsg = '需要创建的文件夹已经存在！';
		}
		$dir = explode('/', $dir);
		foreach($dir as $v){
			if($v){
				$d .= $v . '/';
				if(!is_dir($d)){
					$state = mkdir($d, 0777);
					if(!$state) $this->errmsg = '在创建目录' . $d . '时出错！';
				}
			}
		}
		return true;
	}
	
	/*产生长度为$length的随机数*/
	public function randomkeys($length)
	{
		$pattern = '1234567890abcdefghijklmnopqrstuvwxyz';
		$key	= '';
		$pmax	= strlen($pattern)-1;
		for($i=0;$i<$length;$i++){
			$key .= $pattern{mt_rand(0,$pmax)};
		}
		return $key;
	}
}
//类结束
?>