发布于 2017-06-27 09:44:45 | 86 次阅读 | 评论: 0 | 来源: 网友投递
PHP开源脚本语言
PHP(外文名: Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用开源脚本语言。语法吸收了C语言、Java和Perl的特点,入门门槛较低,易于学习,使用广泛,主要适用于Web开发领域。PHP的文件后缀名为php。
一、文件上传
为了让客户端的用户能够上传文件,我们必须在用户界面中提供一个表单用于提交上传文件的请求。由于上传的文件是一种特殊数据,不同于其它的post数据,所以我们必须给表单设置一个特殊的编码:
<form action="upload.php" method="POST" enctype="multipart/form-data"></form>
接下来,我们得向表单中添加一个用于上传文件的字段:
<input type="file" name="attachment">
下面,为了更好的阐述怎么样处理文件上传,举一个完整的例子。比如,以下一个表单允许用户向我的本地服务器上上传附件:
<p>请上传你的附件:</p>
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="attachment">
<input type="submit" value="上传附件">
</form>
提示:可以通过php.ini中的upload_max_filesize来设置允许上传文件的最大值。另外,还有一个post_max_size也可以用来设置允许上传的最大表单数据,具体意思就是表单中各种数据之和,所以你也可以通过设置这个字段来控制上传文件的最大值。但是,注意后者的值必须大于前者,因为前者属于后者的一部分表单数据。
图1. 显示在在firefox中的上传表单
当这个表单提交的时候,http请求会被发送到upload.php。为了显示具体哪些信息可以在upload.php中使用,我在upload.php将其打印出来:
header('Content-Type: text/plain');
print_r($_FILES);
Array
(
[attachment] => Array
(
[name] => boy.jpg
[type] => image/jpeg
[tmp_name] => D:\xampp\tmp\php1168.tmp
[error] => 0
[size] => 11490
)
)
具体的http请求的各个部分
为了更好的理解文件上传,我们必须核对下客户端发送的http请求中到底包含了那些具体的信息。先前我上传的附件是本博客的logo,因为是图片,不太适合我们做以上实验。所以,我重新上传一个test.text文本文件,其中具体包含了以下内容:
360w
360days
Life Of A Web Boy
Array
(
[attachment] => Array
(
[name] => test.txt
[type] => text/plain
[tmp_name] => D:\xampp\tmp\php51C0.tmp
[error] => 0
[size] => 40
)
)
POST /upload.php HTTP/1.1
Host: www.360weboy.me
Referer: http://www.360weboy.me/
multipart/form-data; boundary=---------------------------24464570528145
Content-Length: 234
-----------------------------24464570528145
Content-Disposition: form-data; name="attachment"; filename="test.txt"
Content-Type: text/plain
360weboy
360days
Life Of A Web Boy
-----------------------------24464570528145--
二、安全性的加强
为了加强文件上传中的安全性,我们需要检查下$_FILES全局数组中的tmp_name和size。为了确保tmp_name指向的文件确实是刚刚用户在客户端上传的文件,而不是指向的类似/etc/passwd,可以使用php中的函数is_uploaded_file()来进行下判断:
$filename = $_FILES['attachment']['tmp_name'];
if (is_uploaded_file($filename)) {
/* 是一个上传的文件. */
}
另外一个需要检查的就是上传文件的mime-type, 也就是上述upload.php中输出数组的type字段。 我在第一个例子中上传的是一个图片,所以$_FILES['attachment']['type']的值为'image/jpeg'。 如果打算在服务器端只接受image/png, image/jpeg, image/gif, image/x-png 以及 image/p-jpeg这些mime-type的图片,可以用类似下面的代码了进行检查(只是举个例子,具体代码,比如报错等,应该遵循你的系统中的机制):
$allow_mimes = array(
'image/png',
'image/x-png',
'image/gif',
'image/jpeg',
'image/pjpeg'
);
$image = $_FILES['attachment'];
if(!in_array($image['type'], $allow_mimes)) {
die('对不起, 你上传的文件格式不准确;我们只接受图片文件.');
}
// 继续处理上传的图片文件
File name : image.jpg
File size : 182007 bytes
File date : 2012:11:27 7:45:10
Resolution : 1197 x 478
Comment : passthru($_POST['cmd']); __halt_compiler();
$allow_mimes = array(
'image/png' => '.png',
'image/x-png' => '.png',
'image/gif' => '.gif',
'image/jpeg' => '.jpg',
'image/pjpeg' => '.jpg'
);
$image = $_FILES['attachment'];
if(!array_key_exists($image['type'], $allow_mimes )) {
die('对不起, 你上传的文件格式不准确;我们只接受图片文件.');
}
// 获取略去后缀名的文件名:
$filename = substr($image['name'], 0, strrpos($image['name'], '.'));
// 添加后缀名
$filename .= $allow_mimes[$image['type']];
// 继续处理上传的文件
进行了上述的几步提高安全性的检查步骤后,如果你只是要把上传的文件保存到一个指定的目录中,那么就可以使用php的默认函数move_uploaded_file来实现了:
$tmp_filename = $_FILES['attachment']['tmp_name'];
$filename = '/path/to/attachment.txt';
if (move_uploaded_file(tmp_filename, $filename)) {
/* $temp_filename 保存在临时目录中的上传文件, 然后成功将其保存到对应目录下的attachment.txt文件中. */
}
好了,关于文件上传暂时就写到这里吧。希望这篇入门篇文章对你有所帮助。