松鼠的博客

导航

php批量上传大文件,快速解决php大文件上传问题

处理这个问题要先明白,多大的文件才能算是大文件?两三百M算不算大文件。

所谓大小其实是一个相对值。和你所处的网络环境,处理的语言有关系。语言不必多少,网络环境嘛,如果你的上传带宽足够大,那么两三百M不算是太的的文件。当然总有一般情况,就目前普遍的带宽,对于PHP处理上百M的文件就算是大文件。

那么PHP是如何处理大文件上传的?

这类有两种方案:第一种,是调整php.ini对上传文件的限。第二种,制就是切片上传。

如果上传一个上百M的文件,第一种需要调整php.ini的哪些信息呢?我把这些信息做了一些梳理:

max_execution_time = 0; //最久执行时间默认是30秒,0为不做限制

max_input_time = 60; //如果应用程序所运行环境处在低速链路上,则需要增加此值以适应接收数据所需的更多时间。

memory_limit = -1; //本指令设定了一个脚本所能够申请到的最大内存字节数,默认值8M。如果不需要任何内存上的限制,必须将其设为 -1。如果内存不够,则可能出现错误:Fatal error: Allowed * * * memory size of X bytes exhausted (tried to allocate Y bytes)

file_uploads = On;//是否允许通过HTTP上传文件的开关,默认为ON即是开

upload_max_filesize = 300M;//所上传的文件的最大大小。默认值2M

post_max_size = 300M;//设定POST数据所允许的最大大小。此设定也影响到文件上传。要上传大文件,该值必须大于 upload_max_filesize。

以上的配置信息来自度娘的。按照自身的业务需求进行分配。在配置之前可以先看一下php默认的参数,就能够很好的理解第一个问题

来一个我自己用webuploader处理过的案例。

1.修改php.ini配置:按照以上配置修改。

2.前端js部,直接复制webuploader修改

var uploaderArea = (function(){

var webUploaderUrl = "__PUBLIC__/plugins/webuploader/";

var uplaodApi = Global.host + 'Admin/game/webUploader';

var uploader = WebUploader.create({

// swf文件路径

swf: webUploaderUrl + 'Uploader.swf',

// 文件接收服务端。

server: uplaodApi,

// 选择文件的按钮。可选。

// 内部根据当前运行是创建,可能是input元素,也可能是flash.

pick: '#packUpload',

// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!

resize: false,

})

// 当有文件被添加进队列的时候

uploader.on( 'fileQueued', function( file ) {

$list = $('#fileList');

$list.append( '

' +

'

' + file.name + '
' +

'

等待上传...

' +

'

' );

});

// 文件上传过程中创建进度条实时显示。

uploader.on( 'uploadProgress', function( file, percentage ) {

var $li = $( '#'+file.id ),

$percent = $li.find('.progress .progress-bar');

// 避免重复创建

if ( !$percent.length ) {

$percent = $('

' +

'

' +

'

' +

'

').appendTo( $li ).find('.progress-bar');

}

$li.find('p.state').text('上传中');

$percent.css( 'width', percentage * 100 + '%' );

});

uploader.on( 'uploadSuccess', function( file,res ) {

$( '#'+file.id ).find('p.state').text('已上传');

$('input[name="package"]').val(res.file.urlpath);

$('input[name="packagesize"]').val(res.file.size);

});

uploader.on( 'uploadError', function( file,res ) {

$( '#'+file.id ).find('p.state').text('上传出错');

});

uploader.on( 'uploadComplete', function( file ) {

$( '#'+file.id ).find('.progress').fadeOut();

});

$('#ctlBtn').click(function(){

uploader.upload();

})

})();

3.服务器端(thinkphp)

/**

* 上传游戏文件接口(原来common中的接口不适用)

* 需要从session中获取游戏ID,动态创建游戏相关目录

*/

public function webUploader(){

if(IS_POST){

$gid = $_SESSION['gid'];

$dir = './Public/upload/games/gid_' . $gid;

$path = pathinfo($_FILES['file']['name']);

$filename = $path['filename'];

if(!is_dir($dir)){

mkdir($dir,0777,true);

}

$config = array(

'maxSize' => 814572800,

'rootPath' => $dir . '/',

'subName' => false,

'saveName' => time() . '_' . $filename

);

$upload = new \Think\Upload($config);// 实例化上传类

// 上传文件

$info = $upload->upload();

if(!$info) {// 上传错误提示错误信息

$this->error($upload->getError());

}else{// 上传成功

$info['file']['urlpath'] = ltrim($upload->rootPath,'.') . $info['file']['savepath'] . $info['file']['savename'];

echo json_encode($info);die;

}

}else{

echo '非法请求';

}

}

利用webuploader调用前端js部分调用服务器端的这个接口,就能非常快速的完成大文件上传的功能。

当然这种方式是耗资源的,瓶颈非常明显。所以有了第二种解决方式。这种方式实现起来复杂了点。webuploader API里有接受,包括后端php的代码都有,这类不再赘述。

 

参考文章:http://blog.ncmem.com/wordpress/2023/10/20/php%e6%89%b9%e9%87%8f%e4%b8%8a%e4%bc%a0%e5%a4%a7%e6%96%87%e4%bb%b6%e5%bf%ab%e9%80%9f%e8%a7%a3%e5%86%b3php%e5%a4%a7%e6%96%87%e4%bb%b6%e4%b8%8a%e4%bc%a0%e9%97%ae%e9%a2%98/

欢迎入群一起讨论

 

 

posted on 2023-10-20 15:32  Xproer-松鼠  阅读(59)  评论(0编辑  收藏  举报