CertaiN ...thank you Ive been searching for a good solid hours to get this working! your answer works x
(PHP 5 >= 5.5.0, PHP 7)
CURLFile 应该与选项
CURLOPT_POSTFIELDS
一同使用用于上传文件。
待上传文件的名称
文件的 MIME type(默认是application/octet-stream)。
上传数据中的文件名称(默认为属性 name )。
CertaiN ...thank you Ive been searching for a good solid hours to get this working! your answer works x
// For backward compatibility,
// convert @ prefixed file names to CurlFile class
// since @ prefix is deprecated as of PHP 5.6
if(is_array($postfields) == true)
{
// Check each post field
foreach($postfields as $key => $value)
{
// Convert values for keys starting with '@' prefix
if(strpos($value, '@') === 0)
{
// Get the file name
$filename = ltrim($value, '@');
// Convert the value to the new class
$postfields[$key] = new CURLFile($filename);
}
}
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
This code should be extended if support for the ';type=mimetype' suffix is needed.
i've seen some downvotes , here is a small example of using curl to upload image .
<?php
$target="http://youraddress.tld/example/upload.php";
# http://php.net/manual/en/curlfile.construct.php
// Create a CURLFile object / procedural method
$cfile = curl_file_create('resource/test.png','image/png','testpic'); // try adding
// Create a CURLFile object / oop method
#$cfile = new CURLFile('resource/test.png','image/png','testpic'); // uncomment and use if the upper procedural method is not working.
// Assign POST data
$imgdata = array('myimage' => $cfile);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $target);
curl_setopt($curl, CURLOPT_USERAGENT,'Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15');
curl_setopt($curl, CURLOPT_HTTPHEADER,array('User-Agent: Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15','Referer: http://someaddress.tld','Content-Type: multipart/form-data'));
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true); // enable posting
curl_setopt($curl, CURLOPT_POSTFIELDS, $imgdata); // post images
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // if any redirection after upload
$r = curl_exec($curl);
curl_close($curl);
?>
There are "@" issue on multipart POST requests.
Solution for PHP 5.5 or later:
- Enable CURLOPT_SAFE_UPLOAD.
- Use CURLFile instead of "@".
Solution for PHP 5.4 or earlier:
- Build up multipart content body by youself.
- Change "Content-Type" header by yourself.
The following snippet will help you :D
<?php
/**
* For safe multipart POST request for PHP5.3 ~ PHP 5.4.
*
* @param resource $ch cURL resource
* @param array $assoc "name => value"
* @param array $files "name => path"
* @return bool
*/
function curl_custom_postfields($ch, array $assoc = array(), array $files = array()) {
// invalid characters for "name" and "filename"
static $disallow = array("\0", "\"", "\r", "\n");
// build normal parameters
foreach ($assoc as $k => $v) {
$k = str_replace($disallow, "_", $k);
$body[] = implode("\r\n", array(
"Content-Disposition: form-data; name=\"{$k}\"",
"",
filter_var($v),
));
}
// build file parameters
foreach ($files as $k => $v) {
switch (true) {
case false === $v = realpath(filter_var($v)):
case !is_file($v):
case !is_readable($v):
continue; // or return false, throw new InvalidArgumentException
}
$data = file_get_contents($v);
$v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));
$k = str_replace($disallow, "_", $k);
$v = str_replace($disallow, "_", $v);
$body[] = implode("\r\n", array(
"Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
"Content-Type: application/octet-stream",
"",
$data,
));
}
// generate safe boundary
do {
$boundary = "---------------------" . md5(mt_rand() . microtime());
} while (preg_grep("/{$boundary}/", $body));
// add boundary for each parameters
array_walk($body, function (&$part) use ($boundary) {
$part = "--{$boundary}\r\n{$part}";
});
// add final boundary
$body[] = "--{$boundary}--";
$body[] = "";
// set options
return @curl_setopt_array($ch, array(
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => implode("\r\n", $body),
CURLOPT_HTTPHEADER => array(
"Expect: 100-continue",
"Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
),
));
}
?>
// Create a CURLFile object
$cfile = curl_file_create('cats.jpg','image/jpeg','test_name');
// Assign POST data
$data = array('test_file' => $cfile);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
Usage Example :
curl_setopt($curl_handle, CURLOPT_POST, 1);
$args['file'] = new CurlFile('filename.png', 'image/png', 'filename.png');
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $args);