php深入浅出图片上传

2. PHP函数getimagesize的具体使用方法4

3. 异步上传图片5

1. Php图片上传

上传步骤:

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";

  }

?>

上面的脚本检测了是否已存在此文件,如果不存在,则把文件拷贝到指定的文件夹。

 

 

2. PHP函数getimagesize的具体使用方法

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。

 

3. 异步上传图片

但是有个问题是,如果用表单提交的方式提交图片,会转到另外一个页面,这是我们不想看到了。所以处理方式有:

用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-Typemultipart/form-data; boundary=---------------------------41184676334

这里指出这个请求是按照multipart/form-data格式进行传递,boundary是“---------------------------41184676334”这样一个字符串。boundary是用来隔开表单中不同的数据的。

可以看出每一部分数据由“——”bounary开始,由“——”bounary“——”表明表单的结束。

原文地址:https://www.cnblogs.com/fredshare/p/2680508.html