收藏
回答

php7.4 上传临时素材无法成功

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>';
?>


最后一次编辑于  2020-10-27
回答关注问题邀请回答
收藏

3 个回答

  • 刘毅 🐲
    刘毅 🐲
    2020-10-27
    下面是我的临时解决方案:使用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(032000)), 010);
        $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);
    
    2020-10-27
    有用 2
    回复 4
    • 朱班
      朱班
      2021-03-14
      请问$params是什么?怎么获得的?
      2021-03-14
      回复
    • 朱班
      朱班
      2021-03-15
      问题解决了原来是文件大小的原因。。。把图片压缩一下就能用了😂
      2021-03-15
      回复
    • Loop
      Loop
      2021-06-06
      大佬牛比,我用的7.4都被坑吐血了,奇葩的是企业微信可以用curl来上传,一切正常,这公众号死活不行,一切值都正常的情况下不返回内容了,真的是太坑了
      2021-06-06
      回复
    • 神经蛙
      神经蛙
      07-03
      方法可行
      07-03
      回复
  • 转瞬即逝
    转瞬即逝
    2023-04-28

    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);//返回结果


    2023-04-28
    有用
    回复
  • 希望你像风一样自由
    希望你像风一样自由
    2020-12-14

    我也遇到这个412的问题了,加上form-data 参数就返回正确的内容了

    $data = array(
          'media' => new \CURLFile('111.jpg'),
          'form-data' => array(
              'filename' => $file->getClientOriginalName(),
              'content-type' => $file->getClientMimeType(), //文件类型
              'filelength' => $file->getMaxFilesize(),
          ),
      );
    
    2020-12-14
    有用
    回复 1
    • 朱班
      朱班
      2021-03-14
      请问$file具体是什么?怎么获得的?
      2021-03-14
      回复
登录 后发表内容
问题标签