所属分类:PHP工具与代码
十、模拟上传文件
(一)基于本地文件上传
在PHP手册的curl_setopt函数中,关于CURLOPT_POSTFIELDS有如下描述:
全部数据使用HTTP协议中的"POST"操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似'para1=val1¶2=val2&...'或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会被设置成multipart/form-data。
对于上传文件,这句话包含两个信息:
1. 要上传文件,post的数据参数必须使用数组,使得Content-Type头将会被设置成multipart/form-data。
2. 要上传文件,在文件名前面加上@前缀并使用完整路径。
注意:PHP 5.5.0起,文件上传建议使用CURLFile代替@
因此,模拟文件上传可以按照如下实现:
(1)单文件上传
[code]
//上传D盘下的test.jpg文件,文件必须存在,否则curl处理失败且没有任何提示,Windows下中文文件名上传失败时,可使用iconv('UTF-8', 'GBK//IGNORE', $filename)转码下文件名再上传。
$data = array('name' => 'Foo', 'file' => '@d:/test.jpg');
注: PHP 5.5.0起,文件上传建议使用CURLFile代替@
$ch = curl_init('http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);[/code]
本地测试的时候,在upload.php文件中打印出$_POST和$_FILES即可验证是否上传成功,如下:
[code] print_r($_POST);
print_r($_FILES);[/code]
输出结果类似:
Array ( [name] => Foo ) Array ( [file] => Array ( [name] => test.jpg [type] => application/octet-stream [tmp_name] => D:\xampp\tmp\php2EA0.tmp [error] => 0 [size] => 139999 ) )
(2)多文件上传
[code] // 注: PHP 5.5.0起,文件上传建议使用CURLFile代替@
// 多文件上传
$data = array(
'input_file[0]' => new CURLFile('d:/1.txt', 'text/plain', 'testfile.txt'),
'input_file[1]' => new CURLFile('d:/2.txt', 'text/plain'),
'input_file[2]' => new CURLFile('d:/3.txt', 'text/plain'),
);
$ch = curl_init('http://demo.zjmainstay.cn/php/curl/curlUploadHandler.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);[/code]
输出结果类似:
[code] Array ( [upload_file] => Array ( [name] => Array ( [0] => 1.txt [1] => 2.txt [2] => 3.txt ) [type] => Array ( [0] => text/plain [1] => text/plain [2] => text/plain ) [tmp_name] => Array ( [0] => /tmp/phpkQ75hZ [1] => /tmp/phpuVB5La [2] => /tmp/phpu1z5fm ) [error] => Array ( [0] => 0 [1] => 0 [2] => 0 ) [size] => Array ( [0] => 2 [1] => 2 [2] => 2 ) ) ) [/code]
(3)CURLOPT_POSTFIELDS使用字符串与数组的区别
关于CURLOPT_POSTFIELDS的赋值,另外补充一句描述:
传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成 multipart/form-data,而然传递一个URL-encoded字符串时,数据会被编码成 application/x-www-form-urlencoded。
即:
[code] curl_setopt($ch, CURLOPT_POSTFIELDS, 'param1=val1¶m2=val2&...');[/code]
和
[code] curl_setopt($ch, CURLOPT_POSTFIELDS, array('param1' => 'val1', 'param2' => 'val2', ...));[/code]
相当于html的form表单中:
[code] <form method="post" action="upload.php">
[/code]
和
[code] <form method="post" action="upload.php" enctype="multipart/form-data">[/code]
的区别。
(一)基于本地文件上传
在PHP手册的curl_setopt函数中,关于CURLOPT_POSTFIELDS有如下描述:
全部数据使用HTTP协议中的"POST"操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似'para1=val1¶2=val2&...'或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会被设置成multipart/form-data。
对于上传文件,这句话包含两个信息:
1. 要上传文件,post的数据参数必须使用数组,使得Content-Type头将会被设置成multipart/form-data。
2. 要上传文件,在文件名前面加上@前缀并使用完整路径。
注意:PHP 5.5.0起,文件上传建议使用CURLFile代替@
因此,模拟文件上传可以按照如下实现:
(1)单文件上传
[code]
//上传D盘下的test.jpg文件,文件必须存在,否则curl处理失败且没有任何提示,Windows下中文文件名上传失败时,可使用iconv('UTF-8', 'GBK//IGNORE', $filename)转码下文件名再上传。
$data = array('name' => 'Foo', 'file' => '@d:/test.jpg');
注: PHP 5.5.0起,文件上传建议使用CURLFile代替@
$ch = curl_init('http://localhost/upload.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);[/code]
本地测试的时候,在upload.php文件中打印出$_POST和$_FILES即可验证是否上传成功,如下:
[code] print_r($_POST);
print_r($_FILES);[/code]
输出结果类似:
Array ( [name] => Foo ) Array ( [file] => Array ( [name] => test.jpg [type] => application/octet-stream [tmp_name] => D:\xampp\tmp\php2EA0.tmp [error] => 0 [size] => 139999 ) )
(2)多文件上传
[code] // 注: PHP 5.5.0起,文件上传建议使用CURLFile代替@
// 多文件上传
$data = array(
'input_file[0]' => new CURLFile('d:/1.txt', 'text/plain', 'testfile.txt'),
'input_file[1]' => new CURLFile('d:/2.txt', 'text/plain'),
'input_file[2]' => new CURLFile('d:/3.txt', 'text/plain'),
);
$ch = curl_init('http://demo.zjmainstay.cn/php/curl/curlUploadHandler.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);[/code]
输出结果类似:
[code] Array ( [upload_file] => Array ( [name] => Array ( [0] => 1.txt [1] => 2.txt [2] => 3.txt ) [type] => Array ( [0] => text/plain [1] => text/plain [2] => text/plain ) [tmp_name] => Array ( [0] => /tmp/phpkQ75hZ [1] => /tmp/phpuVB5La [2] => /tmp/phpu1z5fm ) [error] => Array ( [0] => 0 [1] => 0 [2] => 0 ) [size] => Array ( [0] => 2 [1] => 2 [2] => 2 ) ) ) [/code]
(3)CURLOPT_POSTFIELDS使用字符串与数组的区别
关于CURLOPT_POSTFIELDS的赋值,另外补充一句描述:
传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成 multipart/form-data,而然传递一个URL-encoded字符串时,数据会被编码成 application/x-www-form-urlencoded。
即:
[code] curl_setopt($ch, CURLOPT_POSTFIELDS, 'param1=val1¶m2=val2&...');[/code]
和
[code] curl_setopt($ch, CURLOPT_POSTFIELDS, array('param1' => 'val1', 'param2' => 'val2', ...));[/code]
相当于html的form表单中:
[code] <form method="post" action="upload.php">
[/code]
和
[code] <form method="post" action="upload.php" enctype="multipart/form-data">[/code]
的区别。