php 图片上传有个小BUG,求大神解答。以下是我的一些代码
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php 图片上传有个小BUG,求大神解答。以下是我的一些代码相关的知识,希望对你有一定的参考价值。
$link=mysql_connect('localhost','root','123456');
mysql_query("set names 'UTF8'");
mysql_select_db('zhenyu',$link);
$pkind=$_POST['pkind'];
$pname=$_POST['pname'];
$pshow=$_POST['pshow'];
$mysql=mysql_query("insert into product (pkind,pname,ppicture,pshow) values ('".$pkind."','".$pname."','"."product/".$_FILES["file"]["name"]."','".$pshow."')");//上传文件保存在product文件夹
if($mysql)
move_uploaded_file($_FILES["file"]["tmp_name"],"product/".$_FILES["file"]["name"]);
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: " . "product/" . $_FILES["file"]["name"].'<br />';
echo '<a href="pfabu.html">返回</a>';
echo '<script>alert("success");</script>';
如果上传的图片名不超过3个汉字或者包含英文字符,则一切正常。但是如果图片名字数超过3个且只有汉字跟数字,图片不会上传到指定文件夹,其他的输出语句和数据库都还是正常。
这种情况应该是 move_uploaded_file($_FILES["file"]["tmp_name"],"product/".$_FILES["file"]["name"]);这句话没有执行,可是是为什么呢?
怎么才能解决这个问题,求高手指教
您好,这个是 php 的一个 BUG(毕竟是外国人做的,中文支持不太好)。
PHP 中,上传中文文件基本上都会出错,所以只要在移动文件时,将文件重命名就可以了。
(如果需要原文件名,只需要将原文件名和重命名后的文件名保存在数据库中就可以了)
代码如下(您的代码有一些漏洞与不规范之处,这里已更正):
// 检测文件MIME类型,如果不是图片则阻止本次上传// 不要相信$_FILES['file']['type'],这是可以伪造的
// 如果 PHP >= 5.3.0,则使用finfo函数来获取文件类型
// 因为 PHP >= 5.3.0 放弃了 mime_content_type() 函数
if (version_compare(PHP_VERSION, '5.3.0', '>='))
$f = finfo(FILEINFO_MIME_TYPE);
$ftype = explode('/', finfo_file($f, $_FILES['file']['tmp_name']));
finfo_close($f);
$f = NULL;
if ($ftype[0] !== 'image')
@unlink($_FILES['file']['tmp_file']);
die('文件上传失败!<br />请重新上传。<br /><a href="pfabu.html">返回</a>');
$ftype = NULL;
else
$ftype = explode('/', mime_content_type($_FILES['file']));
if ($ftype[0] !== 'image')
@unlink($_FILES['file']['tmp_file']);
die('文件上传失败!<br />请重新上传。<br /><a href="pfabu.html">返回</a>');
$ftype = NULL;
$link = mysql_connect('localhost','root','123456');
mysql_query('set names \\'UTF8\\'');
mysql_select_db('zhenyu', $link);
// 为了防止SQL注入,对数据进行转义
$pkind = addslashes($_POST['pkind']);
$pname = addslashes($_POST['pname']);
$pshow = addslashes($_POST['pshow']);
$filename_upload = $_FILES['file']['name'];
// Base64 编码后的字符只含有 a-z A-Z 0-9 以及+,/,=
$filename = base64_encode($filename_upload);
// Base64 编码中有一些非文件名可用的字符,把它们替换掉
$filename = strtr($filename, array(
'+' => '.',
'/' => '_',
'=' => '-'
)
);
// 上传后的文件保存在product文件夹
$file_move = 'product/' . $filename;
// 如果文件已存在,则在文件名后加上-和一个随机数
// 当然,这一部分也可以您自己更改,不会影响结果
if(file_exists($file_move))
$rand = '-' . strval(rand(0, 9999));
$file_move .= $rand;
$filename_upload .= $rand;
// 因为 $rand 被其它变量引用,不能直接注销
// 所以将其赋值为 NULL,也可达到同样的释放内存的效果
$rand = NULL;
// 判断文件是否是通过 HTTP POST 上传的
// 这可以用来确保恶意用户无法欺骗程序去访问本不该访问的文件,例如/etc/passwd
if (!is_uploaded($_FILES['file']['tmp_name']))
@unlink($_FILES['file']['tmp_name']);
die('文件上传失败!<br />请重新上传。<br /><a href="pfabu.html">返回</a>');
// 如果文件移动失败,则显示错误信息
// 这样就不会导致数据库存储正常,但文件上传失败的情况了
elseif (!move_uploaded_file($_FILES['file']['tmp_name'], $file_move))
@unlink($_FILES['file']['tmp_name']);
die('文件上传失败!<br />请重新上传。<br /><a href="pfabu.html">返回</a>');
// 这里将重命名后的文件名与原文件名储存在同一个字段中,用竖线(|)隔开
// 读取时只需要用 explode() 分开就可以了
if($mysql = mysql_query("INSERT INTO product(pkind,pname,ppicture,pshow) VALUES('$pkind','$pname','$file_move|$_FILES['file']['name']','$pshow')"))
// 显示文件上传信息
echo 'Upload: ', $filename_upload, '<br />';
echo 'Size: ', strval($_FILES['file']['size'] / 1024.0), ' KB<br />';
echo 'Stored in: ', $file_move, '<br />';
echo '<a href="pfabu.html">返回</a>';
echo '<script>alert("success");</script>';
// 如果存入数据库时失败
// 则显示错误信息
else
@unlink($_FILES['file']['tmp_name']);
die('文件上传失败!<br />请重新上传。<br /><a href="pfabu.html">返回</a>');
这样就可以了。
由于没有测试,代码难免会出现一些错误,请随意指出,谢谢!
另外,您还应该考虑到不同用户上传同一个文件名的文件的情况,最好是为每个用户单独分配一个文件夹。
而且,当一个文件夹下的文件过多(>300)时,会导致读写速度变慢,这一点要注意。
解决:
当一个用户的文件夹下文件有300个时,用户再上传文件,就将新的文件保存在另一个文件夹中(如:用户名加上这个用户已有的文件夹数量)。
如果还有后续问题,可以联系我的邮箱:
blutrex@gmail.com谢谢!
参考技术A 这个BUG我也碰到过,最简单的办法就是把现在的文件名为短MD5+时间,可以防重名的 参考技术B 上传后重新命个名就不存在这个问题了,即在move_upload_file()那里改一下,不要用原来的文件名,重新命个名字,比如 ‘product/’.time().mt_rand(100, 999).'原来图片的后缀';多说几句呀,依代码看这代码不光是一点小BUG,一般人都不会这么写吧,即不做过滤检测也不是判断是否是真实上传的内容,也不判断上传的是不是图片,这应该是楼主拿来自己写的玩的吧, 参考技术C move_uploaded_file($_FILES["file"]["tmp_name"],"product/".$_FILES["file"]["name"])没有后缀名
以上是关于php 图片上传有个小BUG,求大神解答。以下是我的一些代码的主要内容,如果未能解决你的问题,请参考以下文章
Android调用照相机和百度地图开发,百度地图显示界面覆盖了相机界面,求大神解答?
用Java做的毕业设计里加个虚拟的在线支付功能怎么弄?求大神解答,只要有个虚拟的功能就好。急