标签:zendframework2 文件上传 文件上传进度 upload php
修改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));
}
}
ZendFramework2学习笔记 文件上传、文件上传进度
标签:zendframework2 文件上传 文件上传进度 upload php
原文地址:http://blog.csdn.net/liuyangwuhan1980/article/details/41518647