上传步骤:
1、创建一个文件上传表单
<html>
<body>
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>
</body>
</html>
<form> 标签的 enctype 属性规定了在提交表单时要使用哪种内容类型。在表单需要二进制数据时,比如文件内容,请使用 "multipart/form-data"。
<input> 标签的 type="file" 属性规定了应该把输入作为文件来处理。举例来说,当在浏览器中预览时,会看到输入框旁边有一个浏览按钮。
2、创建上传脚本
"upload_file.php" 文件含有供上传文件的代码:
<?php
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: " . $_FILES["file"]["tmp_name"];
}
?>
通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。
第一个参数是表单的 input name,第二个下标可以是 "name", "type", "size", "tmp_name" 或 "error"。就像这样:
$_FILES["file"]["name"] - 被上传文件的名称
$_FILES["file"]["type"] - 被上传文件的类型
$_FILES["file"]["size"] - 被上传文件的大小,以字节计
$_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
$_FILES["file"]["error"] - 由文件上传导致的错误代码
UPLOAD_ERR_OK
值:0; 没有错误发生,文件上传成功。
UPLOAD_ERR_INI_SIZE
值:1; 上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值。
UPLOAD_ERR_FORM_SIZE
值:2; 上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值
UPLOAD_ERR_PARTIAL
值:3; 文件只有部分被上传。
UPLOAD_ERR_NO_FILE
值:4; 没有文件被上传。
值:5; 上传文件大小为0.
3、上传限制
在这个脚本中,我们增加了对文件上传的限制。用户只能上传 .gif 或 .jpeg 文件,文件大小必须小于 20 kb:
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 20000))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Stored in: " . $_FILES["file"]["tmp_name"];
}
}
else
{
echo "Invalid file";
}
?>
注释:对于 IE,识别 jpg 文件的类型必须是 pjpeg,对于 FireFox,必须是 jpeg。这是因为这个函数的type不是由php去读取文件的信息,而是由浏览器提供的。换句话说:同一个文件,不同的浏览器定义的不同文件类型的mime不一样,使用不同的浏览器php返回的type类型是不一样的。 但是用服务器端的php提供的getimagesize函数就能统一图片格式为jpeg。
4、保存被上传的文件
上面的例子在服务器的 PHP 临时文件夹创建了一个被上传文件的临时副本。
这个临时的复制文件会在脚本结束时消失。要保存被上传的文件,我们需要把它拷贝到另外的位置:
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 20000))
{
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " already exists. ";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $_FILES["file"]["name"]);
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
}
}
}
else
{
echo "Invalid file";
}
?>
上面的脚本检测了是否已存在此文件,如果不存在,则把文件拷贝到指定的文件夹。
PHP函数getimagesize是庞大的PHP图形处理函数库中的一种,能够帮助我们取得所需要的图片的长度和宽度。
内容说明:
PHP函数getimagesize可用来取得 gif、jpeg 及 png 三种 www 上图片的高与宽,不需要安装 gd library 就可以使用本函数。返回的数组有四个元素。返回数组的第一个元素 (索引值 0) 是图片的高度,单位是像素 (pixel)。
第二个元素 (索引值 1) 是图片的宽度。第三个元素 (索引值 2) 是图片的文件格式,其值 1 为 gif 格式、 2 为 jpeg/jpg 格式、3 为 png 格式。第四个元素 (索引值 3) 为图片的高与宽字符串,height=xxx width=yyy。
比如在后台需要控制图片的长宽条件,就需要用到getimagesize:
$imgfile = $_FILES["file"]["tmp_name"];
$size = getimagesize($imgfile);
var_dump($size);
看出长1024,高768。
但是有个问题是,如果用表单提交的方式提交图片,会转到另外一个页面,这是我们不想看到了。所以处理方式有:
用iframe的方式异步上传图片。步骤:
1.页面加入隐藏iframe,假如name=xxxx;
2. form的target设置成xxxx;
3.后台上传图片后,向前端输出一个函数如:parent.callback('图片url');
4.页面上定义callback函数,参数为url;
5.图片上传完成后,会调用callback函数;
6.在callback中拿到url,进行进一步的处理。
用flash的方式实现:
用jquery插件实现:
这个插件的原理就是构建一个form,然后用POST的方式提交整个Form。在后台中,通过传递来的Form,得到HttpPostedFile,在获取其中的图片信息,这样就实现后台上传图片了。
实例:
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.3.1.min.js" type="text/javascript"></script>
<script src="Scripts/ajaxfileupload.js" type="text/javascript"></script>
<script type="text/javascript">
function ajaxFileUpload() {
$.ajaxFileUpload
(
{
url: 'handler/UploadImageHandler.ashx?userid=1&name=abc',
secureuri: false,
fileElementId: 'fileToUpload',
dataType: 'html',
beforeSend: function() {
$("#loading").show();
},
complete: function() {
$("#loading").hide();
},
success: function(data, status) {
if (typeof (data.error) != 'undefined') {
if (data.error != '') {
alert(data.error);
} else {
alert(data.msg);
}
}
},
error: function(data, status, e) {
alert(e);
}
}
)
return false;
}
</script>
<form id="form1" runat="server">
<table cellpadding="0" cellspacing="0" class="tableForm">
<thead><tr><th>Ajax File Upload</th></tr>
</thead>
<tbody><tr><td>
<input id="fileToUpload" type="file" size="45" name="fileToUpload" class="input"></td></tr>
<tr><td>Please select a file and click Upload button</td></tr>
</tbody>
<tfoot><tr><td><button class="button" id="buttonUpload" onclick="return ajaxFileUpload();">Upload</button></td></tr>
</tfoot>
</table>
</form>
</body>
补充:
1、multipart/form-data知识
在网络编程中需要向服务器上传文件,multipart/form-data就是浏览器中用表单上传文件的一种方式,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作。enctype="multipart/form-data"是上传二进制数据; form里面的input的值以2进制的方式传过去。表单形式上传附件的一般步骤是:
a、客户端和服务器端简历tcp链接;
b、客户端向服务器端发送数据;上传文件也是向服务器发送请求;
c、客户端按照符合“multipart/form-data”格式的向服务器发送数据。
multipart/form-data格式是怎么样的了,我们来看看文件经过浏览器编码之后是个什么样子:
<!DOCTYPE html>
<html>
<body>
<form action="test.php" method="post" enctype="multipart/form-data">
<label for="file">点击上传:</label>
<input type="file" name="file" id="file"/>
<input type="submit" id="" />
</form>
</body>
</html>
上传的时候进行抓包查看:
Cache-Control | no-store, no-cache, must-revalidate, post-check=0, pre-check=0 |
Connection | Keep-Alive |
Content-Length | 330 |
Content-Type | text/html |
Date | Mon, 10 Sep 2012 11:44:58 GMT |
Expires | Thu, 19 Nov 1981 08:52:00 GMT |
Keep-Alive | timeout=5, max=100 |
Pragma | no-cache |
Server | Apache/2.4.2 (Win32) OpenSSL/1.0.1c PHP/5.4.4 |
Set-Cookie | PHPSESSID=ejpcni1bjcjssk7ka58gq5ft34; path=/ |
X-Powered-By | PHP/5.4.4 |
Accept | text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 |
Accept-Encoding | gzip, deflate |
Accept-Language | zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 |
Host | 127.0.0.1 |
Proxy-Connection | keep-alive |
Referer | http://127.0.0.1/sharexie/input.html |
User-Agent | Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1 |
Content-Length | 7329 |
Content-Type | multipart/form-data; boundary=---------------------------41184676334 |
-----------------------------41184676334
Content-Disposition: form-data; name="file"; filename="图片1.png"
Content-Type: image/png
塒NG
���
IHDR��>�������&����sRGB�����gAMA��睆黙��� pHYs������莖╠��€IDATx^頋K掍(E{Y篃ZEMs祲4媘dl!�9墱uNj
該hr@彲$鐆墁*\r .�<�髑W�?靠~~踅疫搴产④(74癶�?�1 4€f��嗝�簘@1(F{W���楴傦鬃��黪鯫�#a瀝崔滣I政歼|�?揪>�={
��~>�鯒偎/遯�[�X~o鵛繖x-
t迒G葑崩��煦w囟{境�扃徧束缦譯!0~fY訖L7匠崪焩;赒權�n䎬€A���D鴒�?埏笯�
漎喆6�
僈\啵1�.5p
|�0)(Z皗B*�7�=�-縢够劰籂#L
(编码文件省略一部分,太长了)
YXu昩鰥RI瀹杈簈'钧!WWz蟇�;�7絊�|蜛C蛆F
樨J�螳琏铊,v:9�骷爿圭靚xr鹧�fo���渕��1鞕~���|€
L�绹瑙=o>囩柱)痦a'�'农#@�)瓠暬怡簵CH�5@�.��X虇r
簦亱�壑誒� ^�
尟並困窊�)�哮狻帺鉤5p 蹞姁z蠉v{依E郼幆鏨佋��|鸟菄τ��#渆鲛擏茿靓丼�#€流&x��.8>D剤��鑁€忶濋鎤zl�<蟮 �|€
L�绹瑙=铋Z髟cy>�纓�|垀:痒鑀x鎘]*�|€
L�绹瑙=铋Z髟cy>�纓�|垀:痒鑀x鎘]*�|€
L�>>��%@ 蘓��1)勈腫�����IEND瓸`�
-----------------------------41184676334--
这是一个POST请求,所以数据放在请求体之中,而不是放在请求头中。
Content-Type
multipart/form-data; boundary=---------------------------41184676334
这里指出这个请求是按照multipart/form-data格式进行传递,boundary是“
---------------------------41184676334”这样一个字符串。boundary是用来隔开表单中不同的数据的。
可以看出每一部分数据由“——”bounary开始,由“——”bounary“——”表明表单的结束。