ZendFramework2学习笔记 文件上传、文件上传进度
修改php.ini以适应文件的要求:
//php.ini file_uploads = On post_max_size = 600M upload_max_filesize = 600M session.upload_progress.enabled = On session.upload_progress.freq = "1%" session.upload_progress.min_freq = "1"
以上我们限制了文件大小限制在不超过600MB。
关于文件上传进度的获取方式,zf2提供了三个类:
Zend\Progressbar\Upload\ApcProgress Zend\ProgressBar\Upload\SessionProgress Zend\Progressbar\Upload\UploadProgress其中SessionProcess要求php5.4以上,本文以SessionProcess为例,其他2个使用方法一样。
首先创建文件上传的From:
//Test/Form/TestForm.php <?php namespace Test\Form; use Zend\Form\Form; use Zend\InputFilter\InputFilter; use Zend\InputFilter\InputFilterAwareInterface; use Zend\InputFilter\InputFilterInterface; use Zend\InputFilter\InputFilterProviderInterface; use Zend\Validator\File\Extension; use Zend\Validator\File\Size; use Zend\Validator\File\ImageSize; use Zend\Validator\File\MimeType; use Zend\Filter\File\RenameUpload; class TestForm extends Form implements InputFilterProviderInterface{ protected $inputFilter; public function __construct($name = null) { parent::__construct($name?$name:'test'); //添加一个文本框 $this->add(array( 'name' => 'userName', 'type' => 'Text', 'options' => array( 'label' => 'name:', ), 'attributes' => array( 'size' => 60, 'maxlength' => 100, ), )); //添加文件上传input $this->add(array( 'name' => 'u', 'type' => 'File', 'options' => array( 'label' => 'file:', ), 'attributes' => array( 'id' => 'u_e', ), )); //提交按钮 $this->add(array( 'name' => 'send', 'type' => 'Submit', 'attributes' => array( 'value' => 'ok', ), )); } public function getInputFilterSpecification() { //文件上传后保存到临时目录的filter $renameUpload = new RenameUpload(array( "target" => __DIR__."/../../../../../uploads", "randomize" => true, "use_upload_name" => true, )); //验证文件扩展名 $extention = new Extension('png,jpeg,jpg,bmp,gif,mp4'); //验证文件大小 $size = new Size(array('min'=>'1kB', 'max'=>'600MB')); //验证文件MIME类型 $mime = new MimeType(array('image/png','image/jpeg','image/jpg','image/bmp','image/gif','video/mp4','enableHeaderCheck' => true)); return array( 'userName' => array( 'required' => true, 'filters' => array( array('name' => 'StringTrim'), array('name' => 'StringToLower'), ), 'validators' => array( array('name' => 'NotEmpty'), array('name' => 'Alnum'), array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'min' => 3, 'max' => 256, ), ), array( 'name' => 'Db\NoRecordExists', 'options' => array( 'table' => 'user', 'field' => 'name', 'adapter' => $this->adapter, ), ), ), ), 'u' => array( 'required' => true, 'filters' => array( $renameUpload, ), 'validators' => array( $extention, $size, //$imgSize, $mime, ), ), ); } }
然后创建view:
//Test/view/test/test/testform.phtml <?php $this->tform->setAttribute('action', $this->url('test', array('action' => 'testform'))); $this->tform->setAttribute('method', 'POST'); $this->tform->prepare(); echo "<div class='tf'>"; echo '<div>'.$this->form()->openTag($this->tform).'</div>'; //获取文件上传进度必须要使用该view helper,formFileSessionProgress会创建一个id为progress_key的hidden的input记录文件上传进度获取需要的id //SessionProgress对应formFileSessionProgress,ApcProgress对应formFileApcProgress,UploadProgress对应formFileUploadProgress echo $this->formFileSessionProgress(); //文本框 echo '<div>'.$this->formRow($this->tform->get('userName')).'</div>'; //文件input //存在这样的情况:用户第一次提交后,文件上传了并检验通过了,但是文本框检验不过,此时,不需要用户重新再上传一次文件,所以,在此情况下将文件input隐藏起来 echo '<div '.($this->tempFile?'style="display:none"':'').'>'.$this->formRow($this->tform->get('u')).'</div>'; if ($this->tempFile){ echo '<div>'.$this->tempFile['name'].'</div>'; }else{ //上传进度显示 echo '<div><span style="display:block; float:left;">process:</span><span id="proc" style="display:block; margin-left:60px; width:60px; height: 30px; background-color: #dddddd;"></span></div>'; } echo '<div>'.$this->formRow($this->tform->get('send')).'</div>'; echo '<div>'.$this->form()->closeTag().'</div>'; echo "</div>"; echo "<hr />"; ?> <!-- 以下脚本用于定时获取并显示上传进度 --> <script> var progressInterval; function getProgress() { var ul = '/test/uploadprogress?id='+$("#progress_key").val();//上传进度通过控制器test/uploadprogress获取 $.ajax({ type : "GET", url : ul, dataType : "json", success : function(data, textStatus) { if (!data.done) { var value = Math.floor((data.current / data.total) * 100); showProgress(value); } else { showProgress(100); clearInterval(progressInterval); } }, error : function(r, t, r){ } }); } function startProgress() { showProgress(0); progressInterval = setInterval(getProgress, 400); } function showProgress(amount) { $('#proc').html(amount+"%"); } $(document).ready( function(){ $('#test').submit(startProgress); } ); </script>
最后是控制器:
//Test/Controller/TestController.php <?php namespace Test\Controller; use Zend\Mvc\Controller\AbstractActionController; use Zend\Session\Storage\SessionArrayStorage; use Zend\ProgressBar\Upload\SessionProgress; use Zend\View\Model\JsonModel; use Test\Form\TestForm; class TestController extends AbstractActionController { public function testformAction() { $form = new TestForm(); $inputFilter = $form->getInputFilter(); $sessionKey = 'uploadedTempFile'; $sessionStorage = new SessionArrayStorage();//session存储对象,文件上传成功并检验成功后,将信息保存进session,避免用户再次重新上传文件 $tempFile = null; if ($sessionStorage->offsetExists($sessionKey)){ $tempFile = $sessionStorage->offsetGet($sessionKey); } if ($this->getRequest()->isPost()){//用户提交了表单,处理表单数据 $postData = array_merge_recursive(//文件信息合并到postdata数组 $this->getRequest()->getPost()->toArray(), $this->getRequest()->getFiles()->toArray() ); if (isset($tempFile)) {//本次提交不是首次提交,并且session中有用户上传的文件的缓存数据 if (!empty($postData['u']['name'])){//用户重新上传了文件,则原来缓存的文件要清除 $sessionStorage->offsetUnset($sessionKey); $tempFile = null; }else{//用户没有上传新文件,所以,检验表单时不检验file元素 $inputFilter->get('u')->setRequired(false); } } $form->setData($postData); if ($form->isValid()) {//表单检验成功 $data = $form->getData(); if (empty($data['u']) && $tempFile){//用户没有上传新文件,所以,使用session中缓存的文件 $data['u'] = $tempFile; $fileName = $data['u']['name']; $fileMIMEType = $data['u']['type']; $tmpFilePathName = $data['u']['tmp_name']; $fileSize = $data['u']['size']; } //保存表单 //....... //$this->redirect()->toRoute( } else {//表单元素检验失败 $data = $form->getData(); $fileErrors = $form->get('u')->getMessages(); if (empty($fileErrors) && isset($data['u']['error']) && $data['u']['error'] === UPLOAD_ERR_OK ) { $tempFile = $data['u']; $sessionStorage->offsetSet($sessionKey, $tempFile); } } } else {//不是用户提交的表单,清空session中的缓存数据 if ($sessionStorage->offsetExists($sessionKey)){ $sessionStorage->offsetUnset($sessionKey); } $tempFile = null; } return array( 'tform' => $form, 'tempFile' => $tempFile, ); } //获取上传进度的action public function uploadprogressAction() { $id = $this->params()->fromQuery('id', null); $progress = new SessionProgress(); return new JsonModel($progress->getProgress($id)); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。