解决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 mssql 时间格式问题
Jan 13 PHP
php 获取mysql数据库信息代码
Mar 12 PHP
PHP根据IP地址获取所在城市具体实现
Nov 27 PHP
CI框架装载器Loader.php源码分析
Nov 04 PHP
php通过分类列表产生分类树数组的方法
Apr 20 PHP
php简单生成随机数的方法
Jul 30 PHP
thinkPHP实现递归循环栏目并按照树形结构无限极输出的方法
May 19 PHP
php中简单的对称加密算法实现
Jan 05 PHP
thinkPHP通用控制器实现方法示例
Nov 23 PHP
Yii2框架实现登陆添加验证码功能示例
Jul 12 PHP
基于laravel-admin 后台 列表标签背景的使用方法
Oct 03 PHP
PHP中国际化的字符串排序和比较对象详解
Aug 23 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
老照片 - 几十年前的收音机与人
2021/03/02 无线电
php自动跳转中英文页面
2008/07/29 PHP
php 数学运算验证码实现代码
2009/10/11 PHP
PHP 页面编码声明方法详解(header或meta)
2010/03/12 PHP
PHP与C#分别格式化文件大小的代码
2011/05/14 PHP
PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠
2015/09/30 PHP
PHP互换两个变量值的方法(不用第三变量)
2016/11/14 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
jquery做的一个简单的屏幕锁定提示框
2014/03/26 Javascript
javascript生成随机数的方法
2014/05/16 Javascript
jquery append 动态添加的元素事件on 不起作用的解决方案
2015/07/30 Javascript
js实现文本框只允许输入数字并限制数字大小的方法
2015/08/19 Javascript
AngularJS入门教程之更多模板详解
2016/08/19 Javascript
jQuery仿写百度百科的目录树
2017/01/03 Javascript
基于Vue实现tab栏切换内容不断实时刷新数据功能
2017/04/13 Javascript
Vue.js移动端左滑删除组件的实现代码
2017/09/08 Javascript
Javascript中将变量转换为字符串的三种方法
2017/09/19 Javascript
JavaScript动态加载重复绑定问题
2018/04/01 Javascript
countUp.js实现数字动态变化效果
2019/10/17 Javascript
uni-app实现点赞评论功能
2019/11/25 Javascript
javascript实现左右缓动动画函数
2020/11/25 Javascript
python通过装饰器检查函数参数数据类型的方法
2015/03/13 Python
Python正则替换字符串函数re.sub用法示例
2017/01/19 Python
matlab中实现矩阵删除一行或一列的方法
2018/04/04 Python
利用Python检测URL状态
2019/07/31 Python
python 实现在shell窗口中编写print不向屏幕输出
2020/02/19 Python
基于Python爬取股票数据过程详解
2020/10/21 Python
澳大利亚制造的羊皮靴:Original UGG Boots
2017/11/13 全球购物
建设工地安全标语
2014/06/07 职场文书
消防安全宣传口号
2014/06/10 职场文书
我的中国梦演讲稿400字
2014/08/19 职场文书
人民检察院起诉书
2015/05/20 职场文书
《实心球》教学反思
2016/02/23 职场文书
SQL Server代理:理解SQL代理错误日志处理方法
2021/06/30 SQL Server
Javascript设计模式之原型模式详细
2021/10/05 Javascript
JS setTimeout与setInterval的区别
2022/04/20 Javascript