1.用的客户端的js上传组件是plupload,该组件支持分片上传,由于本文主要展示的是Php端的实现,客户端的自己可以自行搜索相关使用
切片的思想就是使用fopen,fread,fwrite等php提供的内置函数来实现ab,wb的覆盖和追加的过程
当分块数量+1 = 总快数的时候,把带后缀的.part去掉就可以了
闲话不多说,上代码:
/**
* 上传文件
*
*
**/
public function uploadFile($params)
{
try {
//上传的时候用到了绝对路径,需要注意下
$upload_path = ROOT_PATH.config('file_path')['file']['path'];
if (isset($params['upload_path'])) {
$upload_path = ROOT_PATH.$params['upload_path'];
}
if (!is_dir($upload_path)) {
mkdir($upload_path, 0777, true);
}
$chunks = isset($params['chunks']) ? intval($params['chunks']) : 0;
$chunk = isset($params['chunk']) ? intval($params['chunk']) : 0;
$save_path = $upload_path.DIRECTORY_SEPARATOR.$params['file_name'];
if ($chunk == 0 && file_exists("{save_path}.part")) {
unlink("{$save_path}.part");
}
if (!$output = fopen("{$save_path}.part", $chunks ? 'ab' : 'wb')) {
throw new \Exception('failed to open output stream');
}
if (!empty($_FILES)) {
if ($_FILES['file']['error']) {
throw new \Exception('Failed to move uploaded file.');
}
if (!$input = @fopen($_FILES['file']['tmp_name'], 'rb')) {
throw new \Exception('Failed to open input stream.');
}
} else {
// 另一种从post方式的multipart获取,相当于http_raw_post_data
if (!$input = @fopen("php://input", "rb")) {
throw new \Exception('Failed to open input stream.');
}
}
//读取的数据流写入文件
while($buff = fread($input, 4096)) {
fwrite($output, $buff);
}
@fclose($output);
@fclose($input);
//如果传完,重命名为正确的名字
if (!$chunks || $chunk == $chunks - 1) {
rename("{$save_path}.part", $save_path);
return array('status' => 'complete');
}
return array('status' => 'uploading');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
return false;
}
代码如上,是不是so easy?