解决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 项目的方法
Jan 02 PHP
在PHP中使用反射技术的架构插件使用说明
May 18 PHP
深入理解PHP中的global
Aug 19 PHP
php常用的url处理函数总结
Nov 19 PHP
PHP MYSQL实现登陆和模糊查询两大功能
Feb 05 PHP
Yii2增加验证码步骤详解
Apr 25 PHP
yii通过小物件生成view的方法
Oct 08 PHP
ThinkPHP实现转换数据库查询结果数据到对应类型的方法
Nov 16 PHP
Laravel创建数据库表结构的例子
Oct 09 PHP
PHP多进程简单实例小结
Nov 09 PHP
php 使用 __call实现重载功能示例
Nov 18 PHP
PHP设计模式入门之状态模式原理与实现方法分析
Apr 26 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
jQuery中的RadioButton,input,CheckBox取值赋值实现代码
2014/02/18 PHP
Yii开启片段缓存的方法
2016/03/28 PHP
PHP多进程编程实例详解
2017/07/19 PHP
php封装db类连接sqlite3数据库的方法实例
2017/12/19 PHP
php依赖注入知识点详解
2019/09/23 PHP
利用ASP发送和接收XML数据的处理方法与代码
2007/11/13 Javascript
学习从实践开始之jQuery插件开发 菜单插件开发
2012/05/03 Javascript
js中split函数的使用方法说明
2013/12/26 Javascript
jquery实现聚光灯效果的方法
2015/02/06 Javascript
javascript实现拖放效果
2015/12/16 Javascript
Bootstrap文件上传组件之bootstrap fileinput
2016/11/25 Javascript
Android中Okhttp3实现上传多张图片同时传递参数
2017/02/18 Javascript
AngularJS 异步解决实现方法
2017/06/12 Javascript
ionic2屏幕适配实现适配手机、平板等设备的示例代码
2017/08/11 Javascript
详解关于Vuex的action传入多个参数的问题
2019/02/22 Javascript
vue使用keep-alive保持滚动条位置的实现方法
2019/04/09 Javascript
微信小程序tabBar 返回tabBar不刷新页面
2019/07/25 Javascript
layer提示框添加多个按钮选择的实例
2019/09/12 Javascript
Vue 打包体积优化方案小结
2020/05/20 Javascript
浅析Python基础-流程控制
2016/03/18 Python
Tensorflow 合并通道及加载子模型的方法
2018/07/26 Python
Django实现网页分页功能
2019/10/31 Python
python GUI库图形界面开发之PyQt5窗口背景与不规则窗口实例
2020/02/25 Python
Python实现手势识别
2020/10/21 Python
Pycharm创建文件时自动生成文件头注释(自定义设置作者日期)
2020/11/24 Python
乔丹诺(Giordano)酒庄德国官网:找到最好的意大利葡萄酒
2017/12/28 全球购物
飞利浦美国官网:Philips美国
2020/02/28 全球购物
俄罗斯极限运动网上商店:Board Shop №1
2020/12/18 全球购物
vue路由实现登录拦截
2021/03/24 Vue.js
《路旁的橡树》教学反思
2014/04/07 职场文书
村主任群众路线个人对照检查材料
2014/09/26 职场文书
企业与个人合作经营协议书
2014/11/01 职场文书
中秋节主题班会
2015/08/14 职场文书
一篇文章看懂MySQL主从复制与读写分离
2021/11/07 MySQL
springboot新建项目pom.xml文件第一行报错的解决
2022/01/18 Java/Android
Python何绘制带有背景色块的折线图
2022/04/23 Python