Zend Framework是流行的PHP开发框架,使用Zend框架,能够方便快捷的实现各项常用功能。这里向你介绍使用Zend框架来创建文件上传功能,该机制能够轻而易举地接收、确认和处理要上传的文件。
一、简介
无论是管理YouTube上的视频、在SlideShare上共享PowerPoint演示文稿,还是使用开源电子商务平台Magento更新在线商店中的商品图像,我们都有用到基于web的文件上传功能。但是,这个功能到底是如何工作的呢?文件是如何从本地机器传送到远程服务器的?本文将向读者详细介绍如何使用流行的Zend框架来创建我们自己的PHP文件上传机制,该机制能够轻而易举地接收、确认和处理要上传的文件。
二、配置处理文件上载的PHP
PHP本身能够通过Web表单来完成文件上载,不过无论使用标准PHP代码还是使用Zend框架来管理文件上传,都有必要花一些时间来检测直接影响PHP的有关功能的配置伪指令,这些指令包括:
◆file_uploads:这个伪指令启用PHP的文件上载功能。在默认情形下,这个伪指令会被启用。
◆upload_max_filesize:这个伪指令定义了要上载的文件的最大尺寸。在默认情形下,这个伪指令被设置为2M。
◆upload_tmp_dir:这个伪指令定义了PHP临时存储要上传的文件的目录,文件在传入最终目的地之前将临时存放于此,该目录是由开发人员指定的。在默认情形下,这个伪指令不会赋值,这意味着PHP将使用系统的默认值,举例来说,许多linux发行版中的临时目录为/tmp。
◆post_max_size:设定POST 数据所允许的最大大小。php默认的post_max_size 为2M。
◆max_execution_time:虽然与文件上载的关系不是非常密切,但是这个伪指令在PHP的文件上载功能中却扮演了一个重要角色,因为它定义了PHP脚本的执行时间。对于尺寸特别大的文件来说,可能需要很长的时间才能传输到文件服务器,所以可以考虑将这个伪指令的默认值即30秒改为60乃至90秒。
三、创建文件上载表单
下面我们将创建一个Web表单示例,它能够用来浏览本地计算机的文件系统以及确定要上传的文件。我们将尽力使该示例保持简单,创建的文件上载表单的外观如图1所示。
这个表单的创建方式跟我们之前创建的其他表单大同小异,只是有一些轻微的区别。用于创建这个表单的HTML代码如清单1所示。按照Zend框架的惯例,我们将这个表单放入名为upload.phtml的视图中,它是名为admin的控制器中动作upload的一部分。
- <form enctype="multipart/form-data" method="post" action="/admin/upload">
- <p>
- What file would you like to upload?<br />
- <input type="file" name="video-upload" size="40" />
- < SPAN>p>
- <p>
- <input type="submit" name="submit" class="submit" value="Upload Video" />
- < SPAN>p>
- < SPAN>form>
在这个表单中,有两处代码需要格外注意:
enctype="multipart/form-data":当我们使用Web表单发送大量的二进制数据的时候,就应该使用这个表单属性。因为诸如电子表格以及视频等文件中含有大量的二进制数据,所以创建文件上载表单时应该包含这个属性。
- <input type="file" name="video-upload" size="40" />
#T#上面这个表单元素会创建允许用户在本地文件系统搜索要上传的文件的表单机制。当提交按钮被按下的时候,这个文件将被上传,并将其发送给表单动作所标识的脚本(本例中,为upload.php)做进一步的处理。
如上所述,文件将被上传给表单的动作属性所标识的脚本。然而,除非该脚本对该文件做实际的处理,否则数据会被丢失。在下一节中,我们将介绍如何使用Zend框架的Zend_File_Transfer组件来处理上传的文件。#p#
四、关于Zend_File_Transfer组件
如同Zend框架的其他强大组件旨在简化我们的开发任务那样,Zend_File_Transfer组件旨在简化从用户的计算机向web服务器上传文件的工作。实际上,这个组件在处理文件上传方面非常灵活,它可以使用诸如FTP和WebDAV协议来传送文件,不过我们这里只讨论它的最初设计意图。让我们首先创建最简单上载动作处理,不过它仍能接收和处理一个上载的文件,如下所示:
- public function uploadAction()
- {
- if ($this->getRequest()->isPost()) {
- $upload = new Zend_File_Transfer_Adapter_Http();
- $upload->setDestination($this->config->uploads->product->supplements);
- if ($upload->receive()) {
- echo "The file has been uploaded!";
- }
- }
- }
为了在下面的描述中轻松引用代码,我们这里为动作代码添加了相应的行号。
04行的代码确定POST请求是否已经提交给了该动作。这对于创建为用户呈现表单以及通过表单提交数据的动作来说都非常有用。
06行的代码调用Zend_File_Transfer类组件,并使用了能够处理通过Web表单提交的数据的HTTP适配器。
08行的代码用于设置文件上传的最终目的地。虽然可以直接向该方法传递一个路径,不过我发现将路径存放到application.ini文件中然后根据需要检索配置参数会更加方便一些。 这允许我们依照要求轻松更改目的地路径,当我们的代码从开发工作站迁移到生产服务器时这一点格外有用。
10行的代码负责接收文件,并将其移动到要求的目的地。
或许您觉得这难以置信,但是这短短的十六行代码的确能够接收并将上传来的文件移动到服务器的预定位置! 然而,现在还不要高兴得太早,因为该脚本缺少接收用户输入时应具备的一个关键步骤,因为这个脚本允许用户上传任意文件,这是万万不可的! 幸运的是,Zend_File_Transfer组件带有检查文件上传处理方面能够想到的所有方面的数据验证方法。
五、对上载的文件进行检验
我们至少希望检查被上传文件的一个或者几个关键特性,如文件的大小,或者MIME类型等。实际上,有多种方法可以用来检索这些特性。举例来说,为了检索文件的MIME类型,我们可在接收文件之后调用getMimeType()方法,具体代码如下所示:
- if ($upload->receive()) {
- echo "The file type is {$upload->getMimeType()}";
- }
如果我们向服务器上传了一个PDF文件,并调用了getMimeType方法,那么将会返回application/x-pdf。当用户只应上传特定类型的文件时,这个方法非常有用。下面是一个例子:
- if ($upload->getMimeType() == "application/x-pdf") {
- $upload->receive();
- echo "File received";
- } else {
- echo "Please upload a PDF";
- }
当然,检查文件大小或者类型只是证实过程的一小部分而已。为了简化验证工作,您可能希望在接收被上传的文件之前来进行这些工作,实际上Zend_File_Transfer组件已经为我们提供了18个验证方法。Zend框架文档提供了这些验证函数的完整说明。我们可能用到的验证函数之一便是ImageSize,它能检查一个被上载图像的大小,以便确保其大小介于给定的最大和最小尺寸之间。在某些情况下,这可能非常有用,例如在需要保持缩略图尺寸保持一致的时候。下面的例子将确保所有上传的图像都为PNG类型,同时其大小符合160×160像素的要求:
- if ($this->getRequest()->isPost()) {
- $upload = new Zend_File_Transfer_Adapter_Http();
- $upload->setDestination($this->config->uploads->product->supplements);
- $upload->addValidator('MimeType', false, 'image/png');
- $upload->addValidator('ImageSize', false,
- array('minwidth' => 160,
- 'maxwidth' => 160,
- 'minheight' => 160,
- 'maxheight' => 160)
- );
- if ($upload->isValid()) {
- $upload->receive();
- echo "File received";
- } else {
- echo "Please upload a file of type PNG and dimensions 160x160 pixels.";
- }
- }
六、进一步阅读
如今,用户驱动的内容已经成为Web的关键组成部分,所以项目的成功可能会取决于数据从用户到web服务器的传送效率。在为用户提供数据上传功能的时候,Zend框架的Zend_File_Transfer组件可以极大的降低开发工作的复杂性!
如果您想进一步了解Zend_File_Transfer组件,请参考Zend框架的Zend_File组件文档;另外,PHP手册的文档也有文件上载方面的介绍;此外,Zend_ProgressBar组件的进一步信息请参考Zend框架的Zend_ProgressBar文档。