解决PHP上传非标准格式的图片pjpeg失败的方法


Posted in PHP onMarch 12, 2017

前一阵子网站新上了相册功能,可最近总发现有一些用户上传的图片文件链接失效,代码检查了很多次,测试也做的比较充分了,但还是会出现上传失败的问题,很是郁闷,今天终于找到了解决办法。

从备份源中找到了用户上传失败的JPG图片,进行上传测试,上传完成后页面提示:

Warning: imagecreatefromjpeg(): ‘/tmp/lalala' is not a valid JPEG file in /path/upload.php on line 1

出现这个Warning是由于GD函数库检测发现是非标准JPEG图片格式导致。

解决方法,如果PHP版本 > 5.1.3,可以在php.ini中增加:

gd.jpeg_ignore_warning = 1

在 MIME 类型中有 image/jpeg 与 image/pjpeg 两种,GD库只认识前者的传统格式,后者是 progressive JPEG 的缩写,啥是pjpeg昵?

这个链接中有详细的解释:

http://www.faqs.org/faqs/jpeg-faq/part1/section-11.html

另外,php.net 中也有相关问题的详细讨论,有兴趣的朋友可以进去看看:

http://bugs.php.net/bug.php?id=29878

另外给大家附上一个实用的PHP多图片文件上传类,支持gif、jpg、jpeg、pjpeg、png格式的多图片上传功能,类中可限制图片类型、上传图片大小、设置上传目录、一些提交判断等功能。其实本类不局限于图片的上传,也可以上传TXT/RAR等文件类型,只是要修饰一下代码,相信你能搞定,下面帖出具体代码:

<?php 
class more_file_upload{
const FILE_PATH='/uploadfile/';//默认文件上传的目录,请自行修改
var file_type;
var file_type_array;
var file_type_real_array;
var file_type_string;
var file_name;
var file_size;
var file_tmp_name;
var file_error;
var handledate;
static totalsize=0;
function __construct(file_name,file_error,file_size,file_tmp_name,file_type){
this->handledate=date('m-d-Y');
if (!empty(file_name)){
this->file_name = file_name;
this->file_error = file_error;
this->file_size = file_size;
this->file_tmp_name = file_tmp_name;
this->file_type = file_type;
this->file_type_array = array('/', 'image/gif', 'image/jpg', 'image/jpeg', 'image/pjpeg', 'image/png');
this->file_type_real_array = array(0.1, 'jpg'=>74707370, 'gif'=>7173, 'bmp'=>6677, 'png'=>807871);
this->show_execute_message(this->file_error,this->file_name,this->file_type,this->file_size);
}
}
function __destruct(){
this->file_name = NULL;
this->file_error = NULL;
this->file_size = NULL;
this->file_tmp_name = NULL;
this->file_type = NULL;
self::totalsize = 0;
}
function show_execute_message(smfileerror,smfilename,smfiletype,smfilesize){
if(smfileerror>0){
switch (smfileerror){
case 1: smfilemessage='<strong>文件超过服务器的约定大小!</strong>';break;
case 2: smfilemessage='<strong>文件超过指定的文件大小!</strong>';break;
case 3: smfilemessage='<strong>文件只上传了部分!</strong>';break;
case 4: echo "this->file_name ".'文件上传失败!<br/>';break;
}
self::__destruct();
}else{
smfiletypeflag = array_search(smfiletype,this->file_type_array);
//进行真实格式验证
if(smfiletypeflag != false){
file = fopen(this->file_tmp_name, "rb");
bin = fread(file, 10);
fclose(file);
strInfo = @unpack("c10chars", bin);
typeCode = intval(strInfo['chars1'].strInfo['chars2']);
smfiletypeflag = array_search(typeCode, this->file_type_real_array);
if(smfiletypeflag == false){ //判断是否是png图片
typeCode = intval(strInfo['chars2'].strInfo['chars3'].strInfo['chars4']);
smfiletypeflag = array_search(typeCode, this->file_type_real_array);
if(smfiletypeflag == false){ //判断是否是jpg图片
$typeCode = intval(strInfo['chars7'].strInfo['chars8'].strInfo['chars9'].strInfo['chars10']);
smfiletypeflag = array_search(typeCode, this->file_type_real_array);
}
}
}
if($smfiletypeflag == false){
$smfilemessage='<strong>文件类型不对,请核实!</strong>';
self::__destruct();
}else{
$resflag = $this->move_file($this->file_tmp_name,this->file_name);
if (resflag == 1){
$smfilemessage = '文件上传成功!';
self::totalsize +=intval($smfilesize);
self::__destruct();
}else{
$smfilemessage = '<strong>文件上传失败!</strong>';
self::__destruct();
}
}
}
$smfilesizeformat = $this->size_BKM(smfilesize);
echo '<tr>
<td align="left" >'.smfilename.'</td>
<td align="center" >'.smfiletype.'</td>
<td align="center" >'.smfilesizeformat.'</td>
<td align="center" >'.smfilemessage.'</td>
</tr>';
}
function move_file(mvfiletmp,mvfilename){ //移动文件
mvfilenamearr = explode('.',basename(mvfilename));
mvfilenamearr[0] = this->rand_string();
mvfilename = implode('.',mvfilenamearr);
if (is_uploaded_file(mvfiletmp)){
uploadfile = self::FILE_PATH."mvfilename";
result = move_uploaded_file(mvfiletmp,uploadfile);
return result;
}
}
function rand_string(){
string = md5(uniqid(rand().microtime()));
return string;
}
function size_BKM(size){ // B/KB/MB单位转换
if(size < 1024)
{
size_BKM = (string)size . " B";
}
elseif(size < (1024 * 1024))
{
size_BKM = number_format((double)(size / 1024), 1) . " KB";
}else
{
size_BKM = number_format((double)(size / (1024*1024)),1)." MB";
}
return size_BKM;
}
}
?>

可将代码复制到PHP文件中,保存文件名为:more_upload_file.class.php,使用时include。

PHP 相关文章推荐
php 执行系统命令的方法
Jul 07 PHP
PHP clearstatcache()函数详解
Mar 02 PHP
JS 网站性能优化笔记
May 24 PHP
php 数组使用详解 推荐
Jun 02 PHP
PHP写UltraEdit插件脚本实现方法
Dec 26 PHP
JSON在PHP中的应用介绍
Sep 08 PHP
关于shopex同步ucenter的redirect问题,导致script不运行
Apr 10 PHP
php中的常用魔术方法总结
Aug 02 PHP
php5.3 不支持 session_register() 此函数已启用的解决方法
Nov 12 PHP
ThinkPHP3.1的Widget新用法
Jun 19 PHP
Laravel jwt 多表(多用户端)验证隔离的实现
Dec 18 PHP
PHP使用POP3读取邮箱接收邮件的示例代码
Jul 08 PHP
Yii2 加载css、js 载静态资源的方法
Mar 10 #PHP
php pdo操作数据库示例
Mar 10 #PHP
yii2简单使用less代替css示例
Mar 10 #PHP
在Mac OS下搭建LNMP开发环境的步骤详解
Mar 10 #PHP
Yii2.0中使用js异步删除示例
Mar 10 #PHP
php实现购物车功能(以大苹果购物网为例)
Mar 09 #PHP
PHP用户管理中常用接口调用实例及解析(含源码)
Mar 09 #PHP
You might like
一些使用频率比较高的php函数
2008/10/03 PHP
PHP开发中常用的字符串操作函数
2011/02/08 PHP
php安全开发 添加随机字符串验证,防止伪造跨站请求
2013/02/14 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
Jquery作者John Resig自己封装的javascript 常用函数
2009/11/09 Javascript
jQuery插件实现表格隔行换色且感应鼠标高亮行变色
2013/09/22 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
jquery实现Ctrl+Enter提交表单的方法
2015/07/21 Javascript
javascript弹出窗口实现代码
2015/11/12 Javascript
javascript实现添加附件功能的方法
2015/11/18 Javascript
jQuery遍历DOM的父级元素、子级元素和同级元素的方法总结
2016/07/07 Javascript
js中的DOM模拟购物车功能
2017/03/22 Javascript
Angular中ng-bind和ng-model的区别实例详解
2017/04/10 Javascript
Webpack执行命令参数详解
2017/06/17 Javascript
bootstrap table表格插件之服务器端分页实例代码
2018/09/12 Javascript
基于JavaScript canvas绘制贝塞尔曲线
2018/12/25 Javascript
axios+Vue实现上传文件显示进度功能
2019/04/14 Javascript
关于layui flow loading占位图的实现方法
2019/09/21 Javascript
关于ligerui子页面关闭后,父页面刷新,重新加载的方法
2019/09/27 Javascript
vue中利用iscroll.js解决pc端滚动问题
2020/02/15 Javascript
Python中列表和元组的相关语句和方法讲解
2015/08/20 Python
Python如何实现MySQL实例初始化详解
2017/11/06 Python
1 行 Python 代码快速实现 FTP 服务器
2018/01/25 Python
用pyqt5 给按钮设置图标和css样式的方法
2019/06/24 Python
linux下python中文乱码解决方案详解
2019/08/28 Python
解析Tensorflow之MNIST的使用
2020/06/30 Python
python中openpyxl和xlsxwriter对Excel的操作方法
2021/03/01 Python
button在IE6/7下的黑边去除方案
2012/12/24 HTML / CSS
Aeropostale官网:美国著名校园品牌及青少年服饰品牌
2019/03/21 全球购物
迪拜领先运动补剂零售品牌中文站:Sporter商城
2019/08/20 全球购物
英国在线药房和在线药剂师:Chemist 4 U
2020/01/05 全球购物
大学军训通讯稿
2014/01/13 职场文书
父亲的菜园教学反思
2014/02/13 职场文书
会计师事务所实习证明
2014/11/16 职场文书
2014年仓管员工作总结
2014/11/18 职场文书
政审证明材料
2015/06/19 职场文书