缘起: 群里小伙帮问了一个问题: 如何下载 A 服务器的文件,然后上传到 B 服务器去,本服务器(C)没有磁盘,要求上传必须使用 multipart/form-data 形式。 很快我在网站找到了这段代码,经测试可以很好的解决问题。 (代码出处: https://blog.csdn.net/cigaogu2521/article/details/100778253)
class UploadPart
{
protected static $url;
protected static $delimiter;
protected static $instance;
public function __construct() {
static::$url = 'http://files.note.so/v1/file_server';
static::$delimiter = uniqid();
}
public function putPart($param) {
$post_data = static::buildData($param);
$curl = curl_init(static::$url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
"Content-Type: multipart/form-data; boundary=" . static::$delimiter,
"Content-Length: " . strlen($post_data)
]);
$response = curl_exec($curl);
curl_close($curl);
$info = json_decode($response, true);
if (!is_array($info['Msg']) && $info['Msg'] == $param['filesize']) {
$param['offset'] = $param['filesize'];
$param['upload'] = '';
return $this->putPart($param);
}
return $response;
}
private static function buildData($param){
$data = '';
$eol = "\r\n";
$upload = $param['upload'];
unset($param['upload']);
foreach ($param as $name => $content) {
$data .= "--" . static::$delimiter . "\r\n"
. 'Content-Disposition: form-data; name="' . $name . "\r\n\r\n"
. $content . "\r\n";
}
$data .= "--" . static::$delimiter . $eol
. 'Content-Disposition: form-data; name="upload"; filename="' . $param['filename'] . '"' . "\r\n"
. 'Content-Type:application/octet-stream'."\r\n\r\n";
$data .= $upload . "\r\n";
$data .= "--" . static::$delimiter . "--\r\n";
return $data;
}
public static function getInstance() {
if(!static::$instance){
static::$instance = new static();
}
return static::$instance;
}
}
关于这段代码我有以下几点补充: 1、首先这段代码使用的 new static 而不是 new self 也就是延迟绑定 2、其次 “- -” 的是文档要求的,必须这么开头,另外 body 必须以 “- -” 结束 3、这个代码实现了(需要后台配合)文件断点续传 4、为什么有的地方写的 “\r\n”,而另一些地方写的 “\r\n\r\n”。这也是文档规定。 5、实际上应该把上传地址由参数传入更加灵活
文档是指: https://www.rfc-editor.org/rfc/pdfrfc/rfc1867.txt.pdf https://www.rfc-editor.org/rfc/pdfrfc/rfc1521.txt.pdf
大概是说使用 multipart/form-data 格式上传文件,必须以 “–” 后接一个随机字符串开头 (文档成为 bountry), body 必须以 “–” 表示结束。 当下一行是头描述时,本行使用一个 “\r\n” 结束,否则以 “\r\n\r\n” 结束。
上面拼接的内容大概会是这个样子 完。
|