在做网站开发的时候,我们经常会碰到让用户上传图片的需求,比如让用户上传 头像,给文章添加 封面图,或者是电商网站的 商品展示图片。这些图片不仅要存储在服务器上,还需要进行一些处理,比如 限制图片大小、检查格式,最常见的就是 生成缩略图,这样可以让网站加载更快,用户体验更好。
这篇文章就来用简单、最通俗的方式,一步步带你搞懂PHP 处理图片上传和生成缩略图的完整过程。即使你是PHP 新手,看完这篇文章也能完全搞定图片上传的功能,并且能写出一个 安全、稳定、好用 的上传系统!
首先,用户在网页上上传图片,一般都是通过 HTML 表单 来完成的。最简单的上传表单代码如下:
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="image">
<input type="submit" value="上传图片">
</form>
你可能会好奇,为什么 enctype="multipart/form-data"
不能省略?因为这个参数的作用是 让浏览器知道表单里有文件要上传,如果不写,服务器就接收不到图片数据了。
用户点击上传后,浏览器会把文件 打包发送 给服务器,然后 PHP 通过 $_FILES
这个 超级全局变量 来获取上传的图片。简单来说,$_FILES
就是存放上传文件信息的一个 数组,它里面包含了上传文件的 文件名、类型、大小、临时存储路径 等信息。
当用户点了 上传按钮 之后,服务器端的 upload.php
代码会接收文件,我们可以这样写:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_FILES['image'])) {
$file = $_FILES['image'];
print_r($file);
}
}
如果你上传了一张图片,代码会输出类似这样的信息:
Array
(
[name] => myphoto.jpg
[type] => image/jpeg
[tmp_name] => /tmp/php1234.tmp
[error] => 0
[size] => 102400
)
这里的 [name]
就是文件的原始名字,比如 myphoto.jpg
,[type]
是文件的 MIME 类型,比如 image/jpeg
,[size]
是文件大小(单位是字节)。
其中最关键的是 [tmp_name]
,这个是文件的 临时存储路径,也就是说,PHP 不会自动存文件,它只是先把图片放到一个临时文件夹,等你手动处理后,它才会真正存到你的服务器里。
如果你不处理,PHP 可能会自动删除这个临时文件,所以我们要用 move_uploaded_file()
函数,把它转移到正式的目录里,比如 uploads/
目录下:
move_uploaded_file($_FILES['image']['tmp_name'], 'uploads/' . $_FILES['image']['name']);
这时候,图片就算正式存储到服务器了!
直接让用户随便上传图片是不行的,因为可能会有人上传超大的文件,甚至 上传病毒文件!所以,我们要做几个安全检查:
首先,我们可以 限制文件类型,只允许上传 JPG、PNG、GIF,这样可以防止有人上传其他乱七八糟的文件,比如 .exe
或者 .php
。
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($_FILES['image']['type'], $allowed_types)) {
die('只允许上传 JPG、PNG 和 GIF 图片');
}
然后,我们要 限制文件大小,比如最多只能上传 2MB,防止有人恶意上传超大文件把服务器弄崩溃:
$max_size = 2 * 1024 * 1024; // 2MB
if ($_FILES['image']['size'] > $max_size) {
die('文件大小不能超过 2MB');
}
最后,我们还要 给文件取个独特的名字,防止用户上传相同名字的文件导致文件被覆盖。可以用 uniqid()
来生成唯一文件名,比如这样:
$ext = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);
$new_name = uniqid() . '.' . $ext;
$target_path = 'uploads/' . $new_name;
move_uploaded_file($_FILES['image']['tmp_name'], $target_path);
这样,每个上传的图片都会有一个独特的名字,比如 64fd2a9b38f3a.jpg
,再也不用担心文件被覆盖了。
上传的原图一般都比较大,如果直接在网页上显示,会影响加载速度。所以我们可以用 PHP 生成缩略图,让图片变小一点。
生成缩略图的方法有很多,最常见的是用 GD 库,PHP 自带的这个库可以用来处理图片,比如缩放、裁剪等。
我们可以写一个函数,把图片缩放到 150x150 的小图:
function createThumbnail($src, $dst, $width = 150, $height = 150) {
list($original_width, $original_height, $type) = getimagesize($src);
switch ($type) {
case IMAGETYPE_JPEG:
$source_image = imagecreatefromjpeg($src);
break;
case IMAGETYPE_PNG:
$source_image = imagecreatefrompng($src);
break;
case IMAGETYPE_GIF:
$source_image = imagecreatefromgif($src);
break;
default:
return false;
}
$thumb_image = imagecreatetruecolor($width, $height);
imagecopyresampled($thumb_image, $source_image, 0, 0, 0, 0, $width, $height, $original_width, $original_height);
imagejpeg($thumb_image, $dst, 90);
imagedestroy($source_image);
imagedestroy($thumb_image);
return true;
}
然后,在上传文件的代码里,调用这个函数自动生成缩略图:
$thumb_path = 'uploads/thumb_' . $new_name;
createThumbnail($target_path, $thumb_path);
这样,每当用户上传图片,服务器都会自动生成一个缩略图,比如原图是 uploads/64fd2a9b38f3a.jpg
,缩略图就是 uploads/thumb_64fd2a9b38f3a.jpg
。
好了,到这里,你已经学会了 完整的 PHP 图片上传和缩略图生成流程!如果你正在开发一个网站,这些技巧都可以直接拿来用,希望能帮到你!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。