文件上传类

闲来无事,整理了一下自己写的文件上传类。在PHP生涯中留下点记忆!!!

<?php
class Upload {
    /*
	* Upload类 包含了文件上传、图片添加水印、图片截取、图片缩略
	* author Ming
	* date 2016-05-14 15:07
	*/
	
	//文件类型
	public $type = array('gif','png','jpg','jpeg');
	
	//文件命名
	public $name;
	
	//上传大小限制,单位B
	public $max_size = 2048000;
	
	//文件保存的目录
	public $path;
	
	//图片访问路径前缀
	public $url_prefix = '';
	
	//是否添加水印,wm_image和wm_text,只能选择其中的一种属性
	//position int 水印位置安排(1-10)【1:左头顶;2:中间头顶;3:右头顶...值空:随机位置】
	public $is_watermark = false;
	
	//给图片添加水印图片,格式 array('image_url','position'); 
	//例:array('../images/watermark.png','9')
	public $wm_image;
	
	//给图片添加水印文字,格式 array('text','fontsize','fontcolor','position'); 
	//例:array('watermark','14','#CC0000','9');
	public $wm_text;
	
	//可以水印图片最小尺寸 array('width','height');
	//例:array(200,200);
	public $min_source_can_wm;
	
	//是否生成缩略图 bool
	public $is_thumb = false;
	
	//缩略图的比例(10% 或者 100px)
	public $thumb_ratio;
	
	//是否截图 bool
	public $is_screenshot = false;
	
	//截图的数据 array('width'=>100,'height'=>100);
	public $screenshot_ratio;
	
	
	//提示说明
	private $msg;
	
	//图片后缀名
	private $exten;
	
	/*
	* 功能介绍:上传文件方法
	* return array 图片路径
	*/
	public function upload_file($FileName=''){
	    if(empty($FileName)){
			foreach($_FILES as $value){
				$file_local = $value['tmp_name'];
				$this->exten = pathinfo($value['name'], PATHINFO_EXTENSION);//后缀名
				$file_error = $value['error'];
				$size = $value['size'];
			}
		}else{
		    $file_local = $_FILES[$FileName]['tmp_name'];
			$this->exten = pathinfo($_FILES[$FileName]['name'], PATHINFO_EXTENSION);//后缀名
			$file_error = $_FILES[$FileName]['error'];
			$size = $_FILES[$FileName]['size'];
		}
		
		//检查保存文件的目录是否存在
		if(!$this->dirfn()){
		    $this->err_code = 1;
            return false;
		}
		
		//检查该后缀名是否允许上传
		if(!in_array($this->exten, $this->type, true)){
		    $this->err_code = 2;
            return false;
		}
		
		//检查该图片的大小
		if($this->max_size < $size){
		    $this->err_code = 3;
            return false;
		}
		
		//文件保存路径
		if(empty($this->name)){
		    $this->name = time().mt_rand(1000,9999);
		}
		$url = $this->path . $this->name . '.' . $this->exten;
		
		//保存
		$result = move_uploaded_file($file_local, $url);
		
		if($result && $file_error==0){
		    chmod($url, 0777);
			$data = array();
			
			//是否生成缩略图片
			if($this->is_thumb){
				$data['thumb'] = $this->set_thumb($url);//缩略图路径
			}
			
			//是否需要截图
			if($this->is_screenshot){
				$data['screenshot'] = $this->set_screenshot($url);//截图路径
			}
			
			//是否添加水印
			if($this->is_watermark){
				if(!$this->watermarkfn($url)){
				    $this->err_code = 11;
                    return false;
				}
			}
			$data['image'] = $this->urlfn($url);//原图路径
			
			return $data;
		}else{
		    switch ($file_error){
				case 1:
					$this->msg = '文件大小超出了服务器的空间大小';
				break;
				case 2:
					$this->msg = '要上传的文件大小超出浏览器限制';
				break;
				case 3:
					$this->msg = '文件仅部分被上传';
				break;
				case 4:
					$this->msg = '没有找到要上传的文件';
				break;
				case 5:
					$this->msg = '服务器临时文件夹丢失';
				break;
				case 6:
					$this->msg = '文件写入到临时文件夹出错';
				break;
			}
			$this->err_code = 4;
            return false;
		}
	}
	
	
	/*
	* 功能介绍:读取图片信息
	* return 图片资源
	*/
	private function get_image_info($url, $exten=''){
		$exten = empty($exten) ? $this->exten : $exten;
		
		//获取图片宽高
		list($width, $height) = getimagesize($url);
		
		//创建画布
		switch($exten){
			case 'jpg':
			case 'jpeg':
				$source = @imagecreatefromjpeg($url);
				break;
			case 'png':
				$source = @imagecreatefrompng($url);
				imagesavealpha($source,true);
				break;
			case 'gif':
				$source = @imagecreatefromgif($url);
				break;
			default:
				$this->msg = '不能创建画布';
				$this->err_code = 6;
                return false;
		}
		
		return array(
		    'width' => $width,
		    'height' => $height,
		    'source' => $source,
		);
	}
	
	/*
	* 功能介绍:生成缩略图
	* return 图片路径
	*/
	private function set_thumb($url){
	    //资源信息
		$info = $this->get_image_info($url);
		
		if(empty($this->thumb_ratio)){
		    $this->err_code = 6;
            return false;
		}
		
		if(stripos($this->thumb_ratio, '%')){
		    $multiple = (float)$this->thumb_ratio; //比例
			$new_width = $info['width'] * $multiple; //缩略图的宽度
			$new_height = $info['height'] * $multiple; //缩略图的高度
			
		}else if(stripos($this->thumb_ratio, 'px')){
		    $new_width = (int)$this->thumb_ratio; //缩略图的宽度
			$new_height = $new_width * $info['height'] / $info['width']; //缩略图的高度
		}
		
		//新建彩色图像
		$thumb = imageCreateTrueColor($new_width, $new_height);
		imagealphablending($thumb, false);
		imagesavealpha($thumb, true);
		
		@imagecopyresized($thumb, $info['source'], 0, 0, 0, 0, $new_width, $new_height, $info['width'], $info['height']);
		
		//缩略图url
		$url_info = pathinfo($url);
		$this->path = $url_info['dirname'].'/s/';
		$s_name = $url_info['basename'];
		$s_url = $this->path . $s_name;//缩略图的路径
		
		if($this->dirfn()){
		    $this->keep_image_info($thumb, $s_url);
			return $this->urlfn($url);
		}else{
		    $this->err_code = 9;
            return false;
		}
	}
	
	/*
	* 功能介绍:截图
	* return 图片路径
	*/
	private function set_screenshot($url){
	    //资源信息
		$info = $this->get_image_info($url);
		
		if(empty($this->screenshot_ratio) || !is_array($this->screenshot_ratio)){
		    $this->err_code = 8;
            return false;
		}
		
		$size = $this->screenshot_ratio;
		
		
		//宽度截图规则:谁小就取谁
		if($size['width'] <= $info['width']){
		    $new_width = $size['width'];
			$start_width = ($info['width'] - $size['width']) / 2; //开始截图的宽度
		}else{
		    $new_width = $info['width'];
			$start_width = 0;
		}
		
		//高度截图规则:谁小就取谁
		if($size['height'] <= $info['height']){
		    $new_height = $size['height']; 
			$start_height = ($info['height'] - $size['height']) / 2; //开始截图的高度
		}else{
		    $new_height = $info['height'];
			$start_height = 0;
		}
		
		//新建彩色图像 
		$screenshot = imageCreateTrueColor($new_width, $new_height);
		imagealphablending($screenshot, false);
		imagesavealpha($screenshot, true);
		
		@imagecopyresized($screenshot, $info['source'], 0, 0, $start_width, $start_height, $new_width, $new_height, $new_width, $new_height);
		
		//截图url
		$url_info = pathinfo($url);
		$this->path = $url_info['dirname'].'/c/';
		$c_name = $url_info['basename'];
		$c_url = $this->path . $c_name;//截图的路径
		
		if($this->dirfn()){
		    $this->keep_image_info($screenshot, $c_url);
			return $this->urlfn($url);
		}else{
		    $this->err_code = 10;
            return false;
		}
	}
	
	/*
	* 功能介绍:添加水印
	*/
	public function watermarkfn($url){
	    //默认
		$this->w_pct = 70; //透明度
		$position = 9; //位置
		$min_size = array(200,200);
		

        if(!$this->check($url)) return false;
		
		//设置范围:少于最小尺寸就不添加水印
		if(!empty($this->min_source_can_wm)){
		    $min_size = $this->min_source_can_wm;
		}
		
		//原图资源信息
		$source_info = getimagesize($url);//图片信息
		$source_w  = $source_info[0];//图片宽度
		$source_h  = $source_info[1];//图片高度
		
		//尺寸少于最小尺寸,不添加水印
		if($source_w < $min_size[0] || $source_h < $min_size[1]) return true;
		
		switch($source_info[2]) { //图片类型
			case 1 : //GIF格式
				$source_img = imagecreatefromgif($url);
				break;
			case 2 : //JPG格式
				$source_img = imagecreatefromjpeg($url);
				break;
			case 3 : //PNG格式
				$source_img = imagecreatefrompng($url);
				imagesavealpha($source_img,true);
				break;
			default :
				return false;
		}
		
		//水印图片
		if(!empty($this->wm_image)){
		    $ifwaterimage = 1; //标记
			
			$water_img = $this->wm_image;
			$w_img = $water_img[0];
			
			//检查水印图片是否有效
			if(!empty($w_img) && file_exists($w_img)){
			    
				//水印图片资源信息
				$water_info  = getimagesize($w_img);
				$width    = $water_info[0];
				$height    = $water_info[1];
				
				switch($water_info[2]) {
					case 1 :
						$wm_source = imagecreatefromgif($w_img);
						break;
					case 2 :
						$wm_source = imagecreatefromjpeg($w_img);
						break;
					case 3 :
						$wm_source = imagecreatefrompng($w_img);
						imagealphablending($w_img,false);
						imagesavealpha($w_img,true);
						break;
					default :
						return;
				}
				$position = empty($water_img[1]) ? $position : $water_img[1];
				
			}else{
			    $this->err_code = 13;
                return false;
			}
			
		//水印文字
		}else if(!empty($this->wm_text)){
		    $ifwaterimage = 0;
			
			$text_info = $this->wm_text;
			$w_text = empty($text_info[0]) ? 'watermark' : $text_info[0];
			$w_font = empty($text_info[1]) ? 14 : $text_info[1];
			$w_color = empty($text_info[2]) ? '#CC0000' : $text_info[2];
			$position = empty($text_info[3]) ? $position : $text_info[3];
			
			$temp = imagettfbbox(ceil($w_font*2.5), 0, './includes/texb.ttf', $w_text); //imagettfbbox返回一个含有 8 个单元的数组表示了文本外框的四个角
			$width = $temp[2] - $temp[6];
			$height = $temp[3] - $temp[7];
			unset($temp);
		}else{
		    $this->err_code = 12;
            return false;
		}
		
		switch($position) {
			case 1:
				$wx = 5;
				$wy = 5;
				break;
			case 2:
				$wx = ($source_w - $width) / 2;
				$wy = 0;
				break;
			case 3:
				$wx = $source_w - $width;
				$wy = 0;
				break;
			case 4:
				$wx = 0;
				$wy = ($source_h - $height) / 2;
				break;
			case 5:
				$wx = ($source_w - $width) / 2;
				$wy = ($source_h - $height) / 2;
				break;
			case 6:
				$wx = $source_w - $width;
				$wy = ($source_h - $height) / 2;
				 break;
			case 7:
				$wx = 0;
				$wy = $source_h - $height;
				break;
			case 8:
				$wx = ($source_w - $width) / 2;
				$wy = $source_h - $height;
				break;
			case 9:
				$wx = $source_w - ($width+5);
				$wy = $source_h - ($height+5);
				break;
			case 10:
				$wx = rand(0,($source_w - $width));
				$wy = rand(0,($source_h - $height));
				break;       
			default:
				$wx = rand(0,($source_w - $width));
				$wy = rand(0,($source_h - $height));
				break;
		}
		
		if($ifwaterimage){
			if($water_info[2] == 3){ //PNG格式
				imagecopy($source_img, $wm_source, $wx, $wy, 0, 0, $width, $height);
			}else{
				imagecopymerge($source_img, $wm_source, $wx, $wy, 0, 0, $width, $height, $this->w_pct);
			}
		}else{
			if(!empty($w_color) && (strlen($w_color)==7)) {
				$r = hexdec(substr($w_color,1,2));
				$g = hexdec(substr($w_color,3,2));
				$b = hexdec(substr($w_color,5));
			}else{
				return;
			}
			imagestring($source_img,$w_font,$wx,$wy,$w_text,imagecolorallocate($source_img,$r,$g,$b));
		}
		
		//输出图片
		switch($source_info[2]) {
			case 1 :
				imagegif($source_img, $url);
				break;
			case 2 :
				imagejpeg($source_img, $url, 80);
				break;
			case 3 :
				imagepng($source_img, $url);
				break;
			default :
				return;
		}
		
		if(isset($wm_source)) {
			imagedestroy($wm_source);
		}
		imagedestroy($source_img);
		return true;
	}
	
	/*鉴定图片信息*/
	public function check($image){
		return extension_loaded('gd') && preg_match("/\.(jpg|jpeg|gif|png)/i", $image, $m) && file_exists($image) && function_exists('imagecreatefrom'.($m[1] == 'jpg' ? 'jpeg' : $m[1]));
	}
	
	/*
	* 功能介绍:保存处理后的图片
	*/
	private function keep_image_info($image_source, $url, $exten=''){
		$exten = empty($exten) ? $this->exten : $exten;
		switch($exten){
			case 'jpg':
			case 'jpeg':
				imagejpeg($image_source, $url, 80);
			    break;
			case 'png':
				imagepng($image_source, $url, 8);
			    break;
			case 'gif':
				imagegif($image_source, $url, 100);
			    break;
		}
		//释放资源
		imagedestroy($image_source);
		return;
	}
	
	/*
	* 功能介绍:检查是否存在目录,如果不存在就创建该目录
	* $dir string 目录
	* return true or false
	*/
	private function dirfn(){
	    $dir = rtrim($this->path, '/').'/';
		if(!file_exists($dir)){
			mkdir($dir,0777,true);
			chmod($dir,0777);
		}
		return is_dir($dir);
	}
	
	/*
	* 功能介绍:路径处理
	* $url string 路径
	* return string
	*/
	private function urlfn($url){
	    if(empty($this->url_prefix)){
			return $url;
		}else{
			return $this->url_prefix . ltrim($url, '../');
		}
	}
	
	/*
	* 功能介绍:错误返回
	* return string
	*/
	public function get_error(){
	    if(!$this->err_code) return false;
        $err_msg = array(
            '0' => $this->msg,
			'1' => $this->path.'目录不存在&创建目录失败,请检查目录权限',
            '2' => '文件类型不符合,允许上传的文件后缀是:'.implode('、',$this->type),
            '3' => '文件大小不符:只允许上传少于2M的图片',
            '4' => '上传失败,原因是:'.$this->msg,
            '5' => '上传文件失败',
            '6' => '图片损坏了'.$this->msg,
			'7' => '请配置好缩略图与原图的比例',
			'8' => '请配置好截取图片的尺寸',
			'9' => '缩略图目录不存在&创建目录失败,请检查目录权限',
			'10' => '截图目录不存在&创建目录失败,请检查目录权限',
			'11' => '添加水印失败',
			'12' => '请设置好添加水印的参数',
			'13' => '水印图片无效,请重新设置或检查水印图片路径',
        );
        return $err_msg[$this->err_code];
	}
}
?>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
用 Java 编写的、协议和平台都独立的服务器端组件,使用请求/响应的模式,提供了一个基于 Java 的服务器解决方案。本文将从文件传输的基本原理入手,分析如何用 java进行文件的上传,并提出解决方案。 一、基本原理 通过 HTML 上载文件的基本流程如下图所示。浏览器端提供了供用户选择提交内容的界面(通常是一个表单),在用户提交请求后,将文件数据和其他表单信息编码并上传至服务器端,服务器端(通常是一个 cgi 程序)将上传的内容进行解 码了,提取出 HTML 表单中的信息,将文件数据存入磁盘或数据库。 -------------------------------------------------------------------------------- 回页首 二、各过程详解 A)填写表单并提交 通过表单提交数据的方法有两种,一种是 GET 方法,另一种是 POST 方法,前者通常用于提交少量的数据,而在上传文件或大量数据时,应该选用 POST 方法。在 HTML 代码中,在 <form> 标签中添加以下代码可以页面上显示一个选择文件的控件。 <input type="file" name="file01"> 在页面中显示如下(可能随浏览器不同而不同) 可以直接在文本框中输入文件名,也可以点击按钮后弹出供用户选择文件的对话框。 B)浏览器编码 在向服务器端提交请求时,浏览器需要将大量的数据一同提交给 Server 端, 而提交前,浏览器需要按照 Server 端可以识别的方式进行编码,对于普通的表单数据,这种编码方式很简单,编码后的结果通常是 field1=value2&field2=value2&… 的形式,如 name=aaaa&Submit=Submit。这种编码的具体规则可以在 rfc2231 里查到, 通常使用的表单也是采用这种方式编码的,Servlet 的 API 提供了对这种 编码方式解码的支持,只需要调用 ServletRequest 中的方法就可以得到 用户表单中的字段和数据。 这种编码方式( application/x-www-form-urlencoded )虽然简单,但对于传输大块的二进制数据显得力不从心,对于传输这数据,浏览器采用了另一种编码方式,即 "multipart/form-data" 的编码方式,采用这种方式,浏览器可以很容易的表单内的数据和文件一起。这种编码方式先定义好一个不可能在数据中出现的字符串作为分界符,然后用它将各个数据段分开,而对于每个数据段都对应着 HTML 页面表单中的一个 Input 区,包括一个 content-disposition 属性,说明了这个数据段的一些信息,如果这个数据段的内容是一个文件,还会有 Content-Type 属性,然后就是数据本身。 这里,我们可以编写一个简单的 Servlet 来看到浏览器到底是怎样编码的。 实现流程: 重载 HttpServlet 中的 doPost 方法 调用 request.getContentLength() 得到 Content-Length ,并定义一个与 Content-Length 大小相等的字节数组 buffer 。 从HttpServletRequest 的实例 request 中得到一个 InputStream, 并把它读入 buffer 中。 使用 FileOutputStream 将 buffer 写入指定文件。 代码清单 // ReceiveServlet.java import java.io.*; import javax.servlet.*; import javax.servlet.http.*; //示例程序:记录下Form提交上来的数据,并存储到Log文件中 public class ReceiveServlet extends HttpServlet { public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { //1 int len = request.getContentLength(); byte buffer[] = new byte[len]; //2 InputStream in = request.getInputStream(); int total = 0; int once = 0;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值