flash图片批量上传处理专用php类


由于某度众所周知的铜臭举动,让我搬离写了5年的渣度空间,准备把技术性的文章定在CSDN了。这些都是文章备份。勿怪。。

鉴于最近有些抓取机器和抄袭者,把标题的【原】字都复制,我不得不声明:本文为 yukon12345原创,转载请注明出处http://blog.csdn.net/yukon12345

昨天晚上写了个flash上传图片处理类。

1.使用gd库检测接收文件的格式,而非普通的后缀名或MIME格式检查。排除jpeg木马。
2.可设定图片存储的高宽限制。超过限制将强制按原宽高比例缩小到限制大小。
3.启用了相关身份认证。
4.接收图片旋转参数,可旋转原图片。
5.日志记录功能。保存图片错误或成功时都有日志记录。
6.详细的utf-8编码的xml格式相关处理反馈。便于flash操作。
调用:
[javascript] view plain copy print ?
  1. <?php
  2. include_once("YImgUpload.class.php");
  3. $upObject=new YImgUpload();
  4. //如设置$upObject->needIdentity=false;将不进行身份认证,便于在flash中调试
  5. $upObject->needIdentity=false;
  6. $upObject->files=$_FILES; //设置file数组。(只能单张)
  7. $upObject->session=$_POST["session"];//设置session_id()
  8. //下面是可选参数。
  9. $upObject->params["rotation"]=$_POST["rotation"];
  10. $upObject->params["cookie"]=$_POST["cookie"];
  11. $upObject->params["allowComment"]=$_POST["allowComment"];
  12. $upObject->params["allowReprint"]=$_POST["allowReprint"];
  13. //请记住先检测,再上传
  14. $upObject->check();
  15. $upObject->upload();
  16. ?>
<?php
include_once("YImgUpload.class.php");
$upObject=new YImgUpload();
//如设置$upObject->needIdentity=false;将不进行身份认证,便于在flash中调试
$upObject->needIdentity=false;
$upObject->files=$_FILES; //设置file数组。(只能单张)
$upObject->session=$_POST["session"]; //设置session_id()
//下面是可选参数。
$upObject->params["rotation"]=$_POST["rotation"];
$upObject->params["cookie"]=$_POST["cookie"];
$upObject->params["allowComment"]=$_POST["allowComment"];
$upObject->params["allowReprint"]=$_POST["allowReprint"];
//请记住先检测,再上传
$upObject->check();
$upObject->upload();
?>


文件处理类。名称:YImgUpload.class.php

[javascript] view plain copy print ?
  1. <?php
  2. /*-----------------------------------------------------------------
  3. * 图片上传处理专用封装类。适合配合flash上传使用。
  4. *@author: yukon12345 http://blog.csdn.net/yukon12345
  5. *默认与flash上传控YUploadImg配合能接受post参数:
  6. *session,(传输而来的session_id()。因为flash上传本身并不能在http头附加session_id来进行认证。)
  7. *rotation,(图片旋转角度)
  8. *cookie(用js获取到的当前浏览器cookie)
  9. *allowComment,allowReprint(存储是否允许评论,允许转帖。现并无特殊用途仅用于日志记录,便于开发时调试)
  10. *默认的$_FILES["Filedata"]flash上传
  11. *-----------------------------------------------------------------------------------------
  12. */
  13. class YImgUpload {
  14. public $needIdentity = true; //是否进行身份认证
  15. public $session = "noSession";//需赋值的session_id。
  16. public $files; //需赋值的$files.为$_FILES
  17. public $params; //次要的附加参数
  18. public $upload_name = "Filedata"; //接收上传来的标示名。flash默认"Filedata"
  19. public $max_file_size_in_bytes = 2097152; //上传大小限制默认2M
  20. public $max_size = 2000; //图片最大宽高注意允许的宽高过大会造成服务器资源消耗。并造成执行30秒超时。
  21. public $MAX_FILENAME_LENGTH = 260; //最长文件名
  22. public $extension_whitelist = array (
  23. "jpg",
  24. "gif",
  25. "png",
  26. "jpeg"
  27. ); // 允许的后缀
  28. public $upload_contain = "/uploads/"; //上传图片所在文件夹
  29. public $log_path = "logs";//日志记录的目录。请确认是否有此文件夹
  30. private $save_path; //保存的路径
  31. private $file_name; //原文件名
  32. private $file_extension = "";
  33. private $pic_titler;
  34. private $uploadErrors = array (
  35. 0 => "",
  36. 1 => "超过最大字节",
  37. 2 => "超过最大字节",
  38. 3 => "文件不完整",
  39. 4 => "无上传文件aaa",
  40. 6 => "找不到暂存路径"
  41. );
  42. private $width;
  43. private $height;
  44. public function YImgUpload() {
  45. }
  46. public function check() {
  47. $this->file_name = $this->files[$this->upload_name]['name'];
  48. $this->save_path = dirname(__FILENAME__) . $this->upload_contain;
  49. if ($this->needIdentity ==false) {
  50. } else {
  51. session_id($this->session);
  52. session_start();
  53. //下面这一部分可修改成你自己的session检测函数
  54. //注释掉这一段将不会验证发送者的身份
  55. if ($_SESSION["check"] !="yukonTestCode") {
  56. $this->HandleError("身份验证错误");
  57. exit (0);
  58. }
  59. }
  60. //参数设置
  61. date_default_timezone_set('PRC'); //设定时区
  62. //检测gd库
  63. if (function_exists("gd_info")) {
  64. //检测是否开启gd库
  65. $gdinfo = gd_info();
  66. $gdversion = $gdinfo['GD Version']; //获得版本号
  67. preg_match("/([0-9])\.([0-9]+)\.([0-9]+)/", $gdversion, $ver);//获得特定版本号
  68. if ($ver[1] < 2 && $ver[3] < 28) //检查库支持。过低版本不能处理gif
  69. {
  70. $this->HandleError("gd低于2.0.28");
  71. exit (0);
  72. }
  73. } else {
  74. $this->HandleError("没有开启gd库");
  75. exit (0);
  76. }
  77. //检测文件大小和POST数据长度
  78. $POST_MAX_SIZE = ini_get('post_max_size'); //获取php中上传限制参数
  79. $unit = strtoupper(substr($POST_MAX_SIZE, -1)); //获取K,M,G
  80. //获取大小倍数
  81. $multiplier = ($unit == 'M' ? 1048576 : ($unit =='K' ? 1024 : ($unit =='G' ? 1073741824 : 1)));
  82. //设定可接收的最大上传字节数。php.ini中限制和你设定的限制中最小的一个。
  83. $max_file_size_in_bytes = $max_file_size_in_bytes > $multiplier * (int) $POST_MAX_SIZE && $POST_MAX_SIZE ? $multiplier * (int) $POST_MAX_SIZE && $POST_MAX_SIZE : $max_file_size_in_bytes;
  84. if ((int) $_SERVER['CONTENT_LENGTH'] > $multiplier * (int) $POST_MAX_SIZE && $POST_MAX_SIZE) {
  85. //header("HTTP/1.1 500 Internal Server Error"); // 触发一个错误
  86. $this->HandleError("文件大小错误");
  87. exit (0);
  88. }
  89. // 初步检查文件
  90. if (!isset ($this->files[$this->upload_name])) {
  91. $this->HandleError("无上传文件");
  92. exit (0);
  93. } else
  94. if (isset ($this->files[$this->upload_name]["error"]) && $this->files[$this->upload_name]["error"] != 0) { //发生错误时
  95. $this->HandleError($this->uploadErrors[$this->files[$this->upload_name]["error"]]);
  96. exit (0);
  97. } else
  98. if (!isset ($this->files[$this->upload_name]["tmp_name"]) || !@ is_uploaded_file($this->files[$this->upload_name]["tmp_name"])) {
  99. $this->HandleError("合法性验证失败");
  100. exit (0);
  101. } else
  102. if (!isset ($this->files[$this->upload_name]['name'])) {
  103. $this->HandleError("无文件名");
  104. exit (0);
  105. }
  106. // 检查php.ini中上传文件大小允许值。
  107. $file_size = @ filesize($this->files[$this->upload_name]["tmp_name"]);
  108. if (!$file_size || $file_size > $this->max_file_size_in_bytes) {
  109. $this->HandleError("文件过大");
  110. exit (0);
  111. }
  112. if ($file_size <= 0) {
  113. $this->HandleError("0字节文件");
  114. exit (0);
  115. }
  116. // 检查文件后缀
  117. $path_info = pathinfo($this->files[$this->upload_name]['name']);
  118. $this->file_extension = strtolower($path_info["extension"]);
  119. $is_valid_extension = false;
  120. $is_valid_extension = in_array($this->file_extension, $this->extension_whitelist);//检查后缀是否在数组中
  121. if (!$is_valid_extension) {
  122. $this->HandleError("文件后缀错误");
  123. exit (0);
  124. }
  125. //如果没有设定旋转就为0度
  126. if (!isset ($params["rotation"])) {
  127. $params["rotation"] = 0;
  128. }
  129. $stamp = time(); //获取时间戳
  130. $pic_title = htmlspecialchars($this->file_name, ENT_QUOTES);//此为可存入数据库的图片标题。需注意防止各种xss攻击和SQL注入。此处仅做特殊字符<>""&编码处理。
  131. $pic_titler = $this->file_name; //此为返回给flash的文件名,用于上传完毕的修改提示
  132. //文件实际在服务器的名字.结合原文件名+暂存名+上传时间的MD5值。
  133. $this->file_name = md5($this->file_name . $stamp . $this->files[$this->upload_name]["tmp_name"]) ."." . $this->file_extension;
  134. //检查同名文件
  135. if (file_exists($this->save_path . $this->file_name)) {
  136. $this->HandleError("已有同名文件");
  137. exit (0);
  138. }
  139. }
  140. /*-----------------------
  141. * 检测上传文件的图片编码,并保存。
  142. * ---------------------------
  143. * */
  144. public function upload() {
  145. //用gd库检查图片的实际编码,并执行相关操作。
  146. if ($isjpeg = @ imagecreatefromjpeg($this->files[$this->upload_name]["tmp_name"])) {//如果是jpeg
  147. 获取原图片大小
  148. $this->width = imagesx($isjpeg);
  149. $this->height = imagesy($isjpeg);
  150. if ($this->width > $this->max_size || $this->height > $this->max_size || $this->params["rotation"] != 0) {
  151. //图片大小超过或者需要旋转,启用gd库特别操作
  152. $new_img = $this->resize_image($isjpeg, $this->params["rotation"]);
  153. if (@ imagejpeg($new_img, $this->save_path . $this->file_name)) {
  154. $this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
  155. } else {
  156. $this->HandleError("无法保存");
  157. exit (0);
  158. }
  159. }//gd库特别操作end
  160. else{//图片不超过大小宽高并且无旋转,直接保存
  161. if (@ move_uploaded_file($this->files[$this->upload_name]["tmp_name"], $this->save_path . $this->file_name)) {
  162. $this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
  163. } else {
  164. $this->HandleError("无法保存");
  165. exit (0);
  166. }
  167. }//直接保存end
  168. } //jpeg完
  169. else
  170. if ($ispng = @ imagecreatefrompng($this->files[$this->upload_name]["tmp_name"])) {//如果是png
  171. //变成合适大小并旋转
  172. 获取原图片大小
  173. $this->width = imagesx($ispng);
  174. $this->height = imagesy($ispng);
  175. if ($this->width > $this->max_size || $this->height > $this->max_size || $this->params["rotation"] != 0) {
  176. //图片大小超过或者需要旋转,启用gd库特别操作
  177. $new_img = $this->resize_image($ispng, $this->params["rotation"]);
  178. if (@ imagepng($new_img, $this->save_path . $this->file_name)) {
  179. $this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
  180. } else {
  181. $this->HandleError("无法保存");
  182. exit (0);
  183. }
  184. }//gd库特别操作end
  185. else{//图片不超过大小宽高并且无旋转,直接保存
  186. if (@ move_uploaded_file($this->files[$this->upload_name]["tmp_name"], $this->save_path . $this->file_name)) {
  187. $this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
  188. } else {
  189. $this->HandleError("无法保存");
  190. exit (0);
  191. }
  192. }//直接保存end
  193. } //png完
  194. else
  195. if ($isgif = @ imagecreatefromgif($this->files[$this->upload_name]["tmp_name"])) {
  196. //如果是gif,由于使用imagegif将只保留一帧图片,因此使用普通文件保存方法。
  197. if (@ move_uploaded_file($this->files[$this->upload_name]["tmp_name"], $this->save_path . $this->file_name)) {
  198. $this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
  199. } else {
  200. $this->HandleError("无法保存");
  201. exit (0);
  202. }
  203. } //gif完
  204. else {
  205. $this->HandleError("图过大或编码错");
  206. exit (0);
  207. }
  208. exit (0);
  209. }
  210. /*------------------------------------------------
  211. * 调整图片大小。宽高大于设定的变小,并旋转图片
  212. * resize_image("文件资源句柄","旋转度")
  213. *
  214. * @param string $source接收待处理的文件资源句柄
  215. * @param int $rotation旋转多少度
  216. * @return handler $new_img返回处理后的文件资源句柄
  217. * -----------------------------------------
  218. * */
  219. private function resize_image($source, $rotation) {
  220. //获取原图片大小
  221. $max = $this->max_size;
  222. if ($this->width < $max && $this->height < $max) {
  223. //宽高都不超过就只做旋转修改
  224. if ($rotation != 0) { //角度为0直接返回
  225. $new_img = imagerotate($source, $rotation, 0);
  226. } else {
  227. $new_img = $source;
  228. }
  229. return $new_img;
  230. } else { //有超过的边
  231. if ($this->width > $max && $this->height > $max) {//都超过时
  232. if ($this->width >= $this->height) {//宽大于高
  233. $new_width = $max; //宽为max
  234. $new_height = $max / ($this->width / $this->height);//保持宽高比
  235. } else {
  236. $new_height = $max;
  237. $new_width = $max / ($this->height / $this->width);
  238. }
  239. } else
  240. if ($this->width > $max) {//只有宽超过
  241. $new_width = $max;
  242. $new_height = $this->height / ($this->width / $max);
  243. } else
  244. if ($this->height > $max) {//只有高超过
  245. $new_height = $max;
  246. $new_width = $this->width / ($this->height / $max);
  247. }
  248. $dest = imagecreatetruecolor($new_width, $new_height);
  249. //调整图片大小。将原图片填充到目的图片上
  250. imagecopyresized($dest, $source, 0, 0, 0, 0, $new_width, $new_height, $this->width, $this->height);
  251. if ($rotation != 0) {
  252. $new_img = imagerotate($dest, $rotation, 0);
  253. } else {
  254. $new_img = $dest;
  255. }
  256. return $new_img;
  257. }
  258. }
  259. /*---------------------------------
  260. * 上传失败后的操作。用于输出xml,并记录相关参数
  261. * 接收参数:
  262. * @param string $message输出给flash的文字提示
  263. * ----------------------------------
  264. * */
  265. private function HandleError($message) {//发生错误时的日志记录。
  266. $xml = "<?xml version='1.0' encoding='utf-8'?>";
  267. $xml .= "<root><information errorId='1' message='" . $message ."'/></root>";
  268. echo $xml;
  269. //下面为日志记录
  270. $log = date("[H:i:s]");
  271. $log .= "【错误消息:】" . $message;
  272. $log .= "【IP:】" . $this->getIP();
  273. $log .= "【用户名:】" . $this->getUser();
  274. $log .= "【Session:】" . $this->session;
  275. $log .= "【文件名:】" . $this->files[$this->upload_name]['name'];
  276. $log .= "【图片字节数:】" . $this->files[$this->upload_name]['size'];
  277. //$log .= "【Cookie:】" . $this->params['cookie'] ;
  278. $log .= "【AllowComment:】" . $this->params['allowComment'];
  279. $log .= "【AllowReprint:】" . $this->params['allowReprint'];
  280. $log .= "【Rotaion:】" . $this->params['rotation'] ."\r\n";
  281. //日志默认目录:logs 请确定是否有这个目录
  282. @ error_log($log, 3, "./" . $this->log_path ."/errorlog" . date("[Y-m-d]") .".log");
  283. }
  284. /*---------------------------------
  285. * 上传完毕后的操作。用于输出xml,并记录上传参数
  286. * 接收参数:
  287. * @param string $message输出给flash的文字提示
  288. * @param string $imgURL图片在服务器的相对地址。
  289. * @param string $title图片原名称。
  290. * ----------------------------------
  291. * */
  292. private function HandleOk($message, $imgURL, $title) {//上传成功时的记录
  293. $xml = "<?xml version='1.0' encoding='utf-8'?>";
  294. $xml .= "<root><information errorId='0' message='" . $message ."'url='" . $imgURL ."' title='" . $this->files[$this->upload_name]['name'] . "' /></root>";
  295. echo $xml;
  296. //下面为日志记录
  297. $log = date("[H:i:s]");
  298. $log .= "【IP:】" . $this->getIP();
  299. $log .= "【用户名:】" . $this->getUser();
  300. $log .= "【Session:】" . $this->session;
  301. //$log .= "【Cookie:】" . $this->params['cookie'] ;
  302. $log .= "【图片字节数:】" . $this->files[$this->upload_name]['size'];
  303. $log .= "【原图片宽高:】" . $this->width ."*" . $this->height;
  304. $log .= "【AllowComment:】" . $this->params['allowComment'];
  305. $log .= "【AllowReprint:】" . $this->params['allowReprint'];
  306. $log .= "【Rotaion:】" . $pthis->arams['rotation'] ."\r\n";
  307. error_log($log, 3, "./" . $this->log_path ."/oklog" . date("[Y-m-d]") .".log");
  308. }
  309. /*----------------------------------
  310. * 返回访问者的IP
  311. * @return IP
  312. * ---------------------------
  313. * */
  314. private function getIP() {//获取上传者IP
  315. if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"),"unknown")) {
  316. $ip = getenv("HTTP_CLIENT_IP");
  317. } else
  318. if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"),"unknown")) {
  319. $ip = getenv("HTTP_X_FORWARDED_FOR");
  320. } else
  321. if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"),"unknown")) {
  322. $ip = getenv("REMOTE_ADDR");
  323. } else
  324. if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'],"unknown")) {
  325. $ip = $_SERVER['REMOTE_ADDR'];
  326. } else {
  327. $ip = "unknown";
  328. }
  329. return ($ip);
  330. }
  331. private function getUser() {
  332. //这里添加获取上传者的网站登陆ID
  333. }
  334. } //class
  335. ?>
<?php


/*-----------------------------------------------------------------
* 图片上传处理专用封装类。适合配合flash上传使用。
 *@author: yukon12345  http://blog.csdn.net/yukon12345
*默认与flash上传控YUploadImg配合能接受post参数:
*session,(传输而来的session_id()。因为flash上传本身并不能在http头附加session_id来进行认证。)
*rotation,(图片旋转角度)
*cookie(用js获取到的当前浏览器cookie)
*allowComment,allowReprint(存储是否允许评论,允许转帖。现并无特殊用途仅用于日志记录,便于开发时调试)
*默认的$_FILES["Filedata"]flash上传
*-----------------------------------------------------------------------------------------
*/
class YImgUpload {

public $needIdentity = true; //是否进行身份认证
public $session = "noSession"; //需赋值的session_id。
public $files; //需赋值的$files.为$_FILES
public $params; //次要的附加参数
public $upload_name = "Filedata"; //接收上传来的标示名。flash默认"Filedata"
public $max_file_size_in_bytes = 2097152; //上传大小限制默认2M
public $max_size = 2000; //图片最大宽高注意允许的宽高过大会造成服务器资源消耗。并造成执行30秒超时。
public $MAX_FILENAME_LENGTH = 260; //最长文件名
public $extension_whitelist = array (
"jpg",
"gif",
"png",
"jpeg"
); // 允许的后缀
public $upload_contain = "/uploads/"; //上传图片所在文件夹
public $log_path = "logs"; //日志记录的目录。请确认是否有此文件夹
private $save_path; //保存的路径
private $file_name; //原文件名
private $file_extension = "";
private $pic_titler;
private $uploadErrors = array (
0 => "",
1 => "超过最大字节",
2 => "超过最大字节",
3 => "文件不完整",
4 => "无上传文件aaa",
6 => "找不到暂存路径"
);
private $width;
private $height;
public function YImgUpload() {
}
public function check() {

$this->file_name = $this->files[$this->upload_name]['name'];
$this->save_path = dirname(__FILENAME__) . $this->upload_contain;
if ($this->needIdentity == false) {

} else {
session_id($this->session);
session_start();
//下面这一部分可修改成你自己的session检测函数
//注释掉这一段将不会验证发送者的身份
if ($_SESSION["check"] != "yukonTestCode") {

$this->HandleError("身份验证错误");
exit (0);
}
}
//参数设置
date_default_timezone_set('PRC'); //设定时区

//检测gd库
if (function_exists("gd_info")) {
//检测是否开启gd库
$gdinfo = gd_info();
$gdversion = $gdinfo['GD Version']; //获得版本号
preg_match("/([0-9])\.([0-9]+)\.([0-9]+)/", $gdversion, $ver); //获得特定版本号
if ($ver[1] < 2 && $ver[3] < 28) //检查库支持。过低版本不能处理gif
{
$this->HandleError("gd低于2.0.28");
exit (0);
}
} else {
$this->HandleError("没有开启gd库");
exit (0);
}

//检测文件大小和POST数据长度
$POST_MAX_SIZE = ini_get('post_max_size'); //获取php中上传限制参数
$unit = strtoupper(substr($POST_MAX_SIZE, -1)); //获取K,M,G
//获取大小倍数
$multiplier = ($unit == 'M' ? 1048576 : ($unit == 'K' ? 1024 : ($unit == 'G' ? 1073741824 : 1)));
//设定可接收的最大上传字节数。php.ini中限制和你设定的限制中最小的一个。
$max_file_size_in_bytes = $max_file_size_in_bytes > $multiplier * (int) $POST_MAX_SIZE && $POST_MAX_SIZE ? $multiplier * (int) $POST_MAX_SIZE && $POST_MAX_SIZE : $max_file_size_in_bytes;

if ((int) $_SERVER['CONTENT_LENGTH'] > $multiplier * (int) $POST_MAX_SIZE && $POST_MAX_SIZE) {
//header("HTTP/1.1 500 Internal Server Error"); // 触发一个错误
$this->HandleError("文件大小错误");
exit (0);
}

// 初步检查文件
if (!isset ($this->files[$this->upload_name])) {
$this->HandleError("无上传文件");

exit (0);
} else
if (isset ($this->files[$this->upload_name]["error"]) && $this->files[$this->upload_name]["error"] != 0) { //发生错误时
$this->HandleError($this->uploadErrors[$this->files[$this->upload_name]["error"]]);
exit (0);
} else
if (!isset ($this->files[$this->upload_name]["tmp_name"]) || !@ is_uploaded_file($this->files[$this->upload_name]["tmp_name"])) {
$this->HandleError("合法性验证失败");
exit (0);
} else
if (!isset ($this->files[$this->upload_name]['name'])) {
$this->HandleError("无文件名");
exit (0);
}

// 检查php.ini中上传文件大小允许值。
$file_size = @ filesize($this->files[$this->upload_name]["tmp_name"]);
if (!$file_size || $file_size > $this->max_file_size_in_bytes) {
$this->HandleError("文件过大");
exit (0);
}

if ($file_size <= 0) {
$this->HandleError("0字节文件");
exit (0);
}

// 检查文件后缀
$path_info = pathinfo($this->files[$this->upload_name]['name']);
$this->file_extension = strtolower($path_info["extension"]);
$is_valid_extension = false;
$is_valid_extension = in_array($this->file_extension, $this->extension_whitelist); //检查后缀是否在数组中

if (!$is_valid_extension) {
$this->HandleError("文件后缀错误");
exit (0);
}

//如果没有设定旋转就为0度
if (!isset ($params["rotation"])) {
$params["rotation"] = 0;
}

$stamp = time(); //获取时间戳
$pic_title = htmlspecialchars($this->file_name, ENT_QUOTES); //此为可存入数据库的图片标题。需注意防止各种xss攻击和SQL注入。此处仅做特殊字符<>""&编码处理。
$pic_titler = $this->file_name; //此为返回给flash的文件名,用于上传完毕的修改提示
//文件实际在服务器的名字.结合原文件名+暂存名+上传时间的MD5值。
$this->file_name = md5($this->file_name . $stamp . $this->files[$this->upload_name]["tmp_name"]) . "." . $this->file_extension;
//检查同名文件
if (file_exists($this->save_path . $this->file_name)) {
$this->HandleError("已有同名文件");
exit (0);
}

}

/*-----------------------
* 检测上传文件的图片编码,并保存。
* ---------------------------
* */

public function upload() {

//用gd库检查图片的实际编码,并执行相关操作。
if ($isjpeg = @ imagecreatefromjpeg($this->files[$this->upload_name]["tmp_name"])) { //如果是jpeg
获取原图片大小
$this->width = imagesx($isjpeg);
$this->height = imagesy($isjpeg);
if ($this->width > $this->max_size || $this->height > $this->max_size || $this->params["rotation"] != 0) {
//图片大小超过或者需要旋转,启用gd库特别操作
$new_img = $this->resize_image($isjpeg, $this->params["rotation"]);

if (@ imagejpeg($new_img, $this->save_path . $this->file_name)) {
$this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
} else {
$this->HandleError("无法保存");
exit (0);
}
}//gd库特别操作end
else{//图片不超过大小宽高并且无旋转,直接保存
if (@ move_uploaded_file($this->files[$this->upload_name]["tmp_name"], $this->save_path . $this->file_name)) {
$this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
} else {
$this->HandleError("无法保存");
exit (0);
}
}//直接保存end
} //jpeg完
else
if ($ispng = @ imagecreatefrompng($this->files[$this->upload_name]["tmp_name"])) { //如果是png
//变成合适大小并旋转
获取原图片大小
$this->width = imagesx($ispng);
$this->height = imagesy($ispng);
if ($this->width > $this->max_size || $this->height > $this->max_size || $this->params["rotation"] != 0) {
//图片大小超过或者需要旋转,启用gd库特别操作
$new_img = $this->resize_image($ispng, $this->params["rotation"]);

if (@ imagepng($new_img, $this->save_path . $this->file_name)) {
$this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
} else {
$this->HandleError("无法保存");
exit (0);
}
}//gd库特别操作end
else{//图片不超过大小宽高并且无旋转,直接保存
if (@ move_uploaded_file($this->files[$this->upload_name]["tmp_name"], $this->save_path . $this->file_name)) {
$this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
} else {
$this->HandleError("无法保存");
exit (0);
}
}//直接保存end
} //png完
else
if ($isgif = @ imagecreatefromgif($this->files[$this->upload_name]["tmp_name"])) {
//如果是gif,由于使用imagegif将只保留一帧图片,因此使用普通文件保存方法。

if (@ move_uploaded_file($this->files[$this->upload_name]["tmp_name"], $this->save_path . $this->file_name)) {
$this->HandleOk("文件保存成功", $this->save_path . $this->file_name, $this->pic_titler);
} else {
$this->HandleError("无法保存");
exit (0);
}

} //gif完
else {
$this->HandleError("图过大或编码错");
exit (0);
}

exit (0);
}
/*------------------------------------------------
* 调整图片大小。宽高大于设定的变小,并旋转图片
* resize_image("文件资源句柄","旋转度")
*
* @param string $source接收待处理的文件资源句柄
* @param int $rotation旋转多少度
* @return handler $new_img返回处理后的文件资源句柄
* -----------------------------------------
* */
private function resize_image($source, $rotation) {
//获取原图片大小
$max = $this->max_size;
if ($this->width < $max && $this->height < $max) {

//宽高都不超过就只做旋转修改
if ($rotation != 0) { //角度为0直接返回
$new_img = imagerotate($source, $rotation, 0);
} else {
$new_img = $source;
}
return $new_img;
} else { //有超过的边
if ($this->width > $max && $this->height > $max) { //都超过时
if ($this->width >= $this->height) { //宽大于高
$new_width = $max; //宽为max
$new_height = $max / ($this->width / $this->height); //保持宽高比
} else {
$new_height = $max;
$new_width = $max / ($this->height / $this->width);
}
} else
if ($this->width > $max) { //只有宽超过
$new_width = $max;
$new_height = $this->height / ($this->width / $max);
} else
if ($this->height > $max) { //只有高超过
$new_height = $max;
$new_width = $this->width / ($this->height / $max);
}
$dest = imagecreatetruecolor($new_width, $new_height);
//调整图片大小。将原图片填充到目的图片上
imagecopyresized($dest, $source, 0, 0, 0, 0, $new_width, $new_height, $this->width, $this->height);
if ($rotation != 0) {
$new_img = imagerotate($dest, $rotation, 0);
} else {
$new_img = $dest;
}
return $new_img;
}
}

/*---------------------------------
* 上传失败后的操作。用于输出xml,并记录相关参数
* 接收参数:
* @param string $message输出给flash的文字提示
* ----------------------------------
* */

private function HandleError($message) { //发生错误时的日志记录。
$xml = "<?xml version='1.0' encoding='utf-8'?>";
$xml .= "<root><information errorId='1' message='" . $message . "'/></root>";
echo $xml;
//下面为日志记录
$log = date("[H:i:s]");
$log .= "【错误消息:】" . $message;
$log .= "【IP:】" . $this->getIP();
$log .= "【用户名:】" . $this->getUser();
$log .= "【Session:】" . $this->session;
$log .= "【文件名:】" . $this->files[$this->upload_name]['name'];
$log .= "【图片字节数:】" . $this->files[$this->upload_name]['size'];
//$log .= "【Cookie:】" . $this->params['cookie'] ;
$log .= "【AllowComment:】" . $this->params['allowComment'];
$log .= "【AllowReprint:】" . $this->params['allowReprint'];
$log .= "【Rotaion:】" . $this->params['rotation'] . "\r\n";
//日志默认目录:logs 请确定是否有这个目录
@ error_log($log, 3, "./" . $this->log_path . "/errorlog" . date("[Y-m-d]") . ".log");

}

/*---------------------------------
* 上传完毕后的操作。用于输出xml,并记录上传参数
* 接收参数:
* @param string $message输出给flash的文字提示
* @param string $imgURL图片在服务器的相对地址。
* @param string $title图片原名称。
* ----------------------------------
* */

private function HandleOk($message, $imgURL, $title) { //上传成功时的记录
$xml = "<?xml version='1.0' encoding='utf-8'?>";
$xml .= "<root><information errorId='0' message='" . $message . "'url='" . $imgURL . "' title='" . $this->files[$this->upload_name]['name'] . "' /></root>";
echo $xml;
//下面为日志记录
$log = date("[H:i:s]");
$log .= "【IP:】" . $this->getIP();
$log .= "【用户名:】" . $this->getUser();
$log .= "【Session:】" . $this->session;
//$log .= "【Cookie:】" . $this->params['cookie'] ;
$log .= "【图片字节数:】" . $this->files[$this->upload_name]['size'];
$log .= "【原图片宽高:】" . $this->width . "*" . $this->height;
$log .= "【AllowComment:】" . $this->params['allowComment'];
$log .= "【AllowReprint:】" . $this->params['allowReprint'];
$log .= "【Rotaion:】" . $pthis->arams['rotation'] . "\r\n";
error_log($log, 3, "./" . $this->log_path . "/oklog" . date("[Y-m-d]") . ".log");
}
/*----------------------------------
* 返回访问者的IP
* @return IP
* ---------------------------
* */
private function getIP() { //获取上传者IP
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown")) {
$ip = getenv("HTTP_CLIENT_IP");
} else
if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown")) {
$ip = getenv("HTTP_X_FORWARDED_FOR");
} else
if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown")) {
$ip = getenv("REMOTE_ADDR");
} else
if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")) {
$ip = $_SERVER['REMOTE_ADDR'];
} else {
$ip = "unknown";
}
return ($ip);
}

private function getUser() {
//这里添加获取上传者的网站登陆ID
}

} //class
?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值