php7.4使用curl上传临时素材,API返回空白(The requested URL returned error: 412 Precondition Failed),http状态码412
https://developers.weixin.qq.com/doc/offiaccount/Asset_Management/New_temporary_materials.html
同样的反馈帖子:
https://developers.weixin.qq.com/community/develop/doc/000a6ca7ae4988a4d9f949d4456800
https://developers.weixin.qq.com/community/develop/doc/0004089f8d078823aef9b63655b400
<?php
# 下面是我的测试代码:
$url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=...&type=image';
$data = [
'media' => new CURLFile('F:\web\30101441194a79ab.jpg')
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$res= curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
echo '<pre>';
var_dump($res);
var_dump($info);
echo '</pre>';
?>
下面是我的临时解决方案:使用fsock自己写了个上传。。。 /** * 临时上传 * * @param string $url * @param array $params * @return string */ function api_upload(string $url, array $params = []): string { $timeout = 20; $urls = parse_url($url); $scheme = $urls['scheme']; $port = $urls['port'] ?? ($scheme == 'https' ? 443 : 80); $host = $urls['host']; $boundary = '---------------------------' . substr(md5(rand(0, 32000)), 0, 10); $data = '--' . $boundary . "\r\n"; foreach ($params as $key => $val) { if ($val instanceof CURLFile) { $filename = $val->getPostFilename(); $mimetype = $val->getMimeType(); $content = file_get_contents($val->getFilename()); $data .= "content-disposition: form-data; name=\"" . $key . "\"; filename=\"" . $filename . "\"\r\n"; $data .= "content-type: " . $mimetype . "\r\n\r\n"; $data .= $content . "\r\n"; $data .= "--" . $boundary . "\r\n"; } else { $data .= "Content-Disposition: form-data; name=\"" . $key . "\"\r\n"; $data .= "Content-type:text/plain\r\n\r\n"; $data .= rawurlencode($val) . "\r\n"; $data .= "--$boundary\r\n"; } } $data .= "--\r\n\r\n"; $out = "POST " . $url . " HTTP/1.1\r\n"; $out .= "host: " . $host . "\r\n"; $out .= "content-type: multipart/form-data; boundary=" . $boundary . "\r\n"; $out .= "content-length: " . strlen($data) . "\r\n"; $out .= "connection: close\r\n\r\n"; $out .= $data; if ($scheme == 'https') { $context = stream_context_create([ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false ] ]); $hostname = "ssl://$host:$port"; $fp = stream_socket_client($hostname, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context); } else { $fp = fsockopen($host, $port, $errno, $errstr, $timeout); } fputs($fp, $out); $res = ''; while ($row = fread($fp, 4096)) { $res .= $row; } fclose($fp); $pos = strpos($res, "\r\n\r\n"); $res = substr($res, $pos + 4); return $res; } $token = '...'; $r = api_upload("https://api.weixin.qq.com/cgi-bin/media/upload?access_token=$token&type=image",[ 'media' => new CURLFile('F:\web\aaa.jpg', 'image/jpeg', 'aaa.jpg'), ]); var_dump($r);
php7 我来个简单的
<?php
$url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=$token&type=image';
$file_data = array("media" => new \CURLFile('22.jpg')); //22.jpg为服务器的绝对路径
$ch = curl_init();
curl_setopt($ch , CURLOPT_URL , $url);
curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch , CURLOPT_POST, 1);
curl_setopt($ch , CURLOPT_POSTFIELDS, $file_data);
$output = curl_exec($ch);
curl_close($ch);//关闭会话
print_r($output);//返回结果
我也遇到这个412的问题了,加上form-data 参数就返回正确的内容了
$data = array( 'media' => new \CURLFile('111.jpg'), 'form-data' => array( 'filename' => $file->getClientOriginalName(), 'content-type' => $file->getClientMimeType(), //文件类型 'filelength' => $file->getMaxFilesize(), ), );