PHP 里 curl POST 提交文件到底应该怎么写呀 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mashirozx
V2EX    PHP

PHP 里 curl POST 提交文件到底应该怎么写呀

  •  
  •   mashirozx 2019-11-14 13:51:23 +08:00 5952 次点击
    这是一个创建于 2162 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想用 PHP 上传文件到图床(只接受 form data ),普通的 curl 是这样的,正常:

    curl \ -F "[email protected]" \ -H "Content-Type: multipart/form-data" \ https://sm.ms/api/v2/upload 

    但是用 PHP 一写,返回的都是 bool(false)string(0) ""

    <?php $url = "https://sm.ms/api/v2/upload"; $headers = array(); array_push($headers, "Content-Type: multipart/form-data"); array_push($headers, "User-Agent: ".$_SERVER['HTTP_USER_AGENT']); // $fields = array('smfile' => curl_file_create('test.png', 'image/png', 'test.png')); $fields = array('smfile' => new CURLFile('test.png', 'image/png', 'tset.png')); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); var_dump(curl_exec($ch)); var_dump(curl_error($ch)); 

    求助(*。>Д<)o

    15 条回复    2019-11-20 18:14:21 +08:00
    pota
        1
    pota  
       2019-11-14 14:04:39 +08:00
    $fields = array('smfile' => "@favicon-original.png");
    mashirozx
        2
    mashirozx  
    OP
       2019-11-14 14:54:04 +08:00
    @pota #1 试了这样的写法,但是接口返回的是资源无效。检查了 curl 的 request header,发现 ["content_type"]=> string(24) "text/html; charset=",header 里面的 size_upload 大小好像也太小了,不像是图片,所以看起来好像图片并没有被上传,只是上传了 @favicon-original.png 几个字?萌新我不是太懂,请耐心~
    young
        3
    young  
       2019-11-14 15:05:08 +08:00
    mashirozx
        4
    mashirozx  
    OP
       2019-11-14 15:13:05 +08:00 via Android
    @young 我要是在 Google 查到解决方法就不会在这里问了
    pota
        5
    pota  
       2019-11-14 15:20:41 +08:00
    royantar
        6
    royantar  
       2019-11-14 15:28:00 +08:00
    User-Agent 随便填一些字符试试,别用$_SERVER['HTTP_USER_AGENT']。
    justfindu
        7
    justfindu  
       2019-11-14 15:28:02 +08:00
    试试文件使用绝对地址
    pota
        8
    pota  
       2019-11-14 15:29:56 +08:00   1
    ```
    <?php

    $url = "https://sm.ms/api/v2/upload";
    $headers = array();
    array_push($headers, "Content-Type: multipart/form-data");
    //agent 我复制的我浏览器的 你换乘你对应的就行了
    array_push($headers, "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36");
    $file_path = 'your file path';
    if (function_exists('curl_file_create')) {
    $cFile = curl_file_create($file_path);
    } else { //
    $cFile = '@' . realpath($file_path);
    }
    $fields = array('smfile' => $cFile);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_POST,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

    $result=curl_exec ($ch);
    curl_close($ch);

    var_dump(curl_exec($ch));
    ```
    liuxu
        9
    liuxu  
       2019-11-14 16:04:37 +08:00
    google: sm.ms 403

    t/369007

    ```bash
    liuxu:/tmp$ cat post.php
    <?php

    $ch = curl_init();
    $fd = curl_file_create('/home/liuxu/Downloads/1.png', 'image/png', '1.png');
    $file = array('smfile' => $fd);

    curl_setopt($ch, CURLOPT_URL, "https://sm.ms/api/v2/upload");
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data', 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $file);
    $rs = curl_exec($ch);
    curl_close($ch);
    var_dump($rs);
    ?>
    liuxu:/tmp$ php post.php
    * Trying 47.88.229.110...
    * TCP_NODELAY set
    * Connected to sm.ms (47.88.229.110) port 443 (#0)
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    * CAfile: /etc/ssl/certs/ca-certificates.crt
    CApath: /etc/ssl/certs
    * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
    * ALPN, server accepted to use http/1.1
    * Server certificate:
    * subject: OU=Domain Control Validated; OU=ShinoSaki MDV; CN=sm.ms
    * start date: Jan 2 00:00:00 2017 GMT
    * expire date: Jan 2 23:59:59 2020 GMT
    * subjectAltName: host "sm.ms" matched cert's "sm.ms"
    * issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server CA
    * SSL certificate verify ok.
    > POST /api/v2/upload HTTP/1.1
    Host: sm.ms
    Accept: */*
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
    Content-Length: 59028
    Content-Type: multipart/form-data; boundary=------------------------0dc5337c392dd914
    Expect: 100-continue

    < HTTP/1.1 100 Continue
    < HTTP/1.1 200 OK
    < Server: nginx
    < Date: Thu, 14 Nov 2019 08:02:36 GMT
    < Content-Type: text/html; charset=
    < Transfer-Encoding: chunked
    < Connection: keep-alive
    < Vary: Accept-Encoding
    < Set-Cookie: PHPSESSID=1qsrkiqn676norodn0qnl3peln; path=/
    < Expires: Thu, 19 Nov 1981 08:52:00 GMT
    < Cache-Control: no-store, no-cache, must-revalidate
    < Pragma: no-cache
    < Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
    < X-Frame-Options: SAMEORIGIN
    < X-Content-Type-Options: nosniff
    < X-XSS-Protection: 1; mode=block
    < X-Custom-Job: If you see this, please contact [email protected] for a job
    < Access-Control-Allow-Origin: *
    < Access-Control-Allow-Methods: OPTIONS, HEAD, GET, POST
    < Allow: GET, POST, HEAD
    < Set-Cookie: cid=rBWawl3NChysdVkosGLAg==; expires=Thu, 31-Dec-37 23:55:55 GMT; domain=sm.ms; path=/
    <
    * Connection #0 to host sm.ms left intact
    string(481) "{"success":true,"code":"success","message":"Upload success.","data":{"file_id":0,"width":715,"height":645,"filename":"1.png","storename":"rng9GNzEhBCMUQA.png","size":58844,"path":"\/2019\/11\/14\/rng9GNzEhBCMUQA.png","hash":"QChs79nUXbdZW6ygYDVOBvjGNe","url":"https:\/\/i.loli.net\/2019\/11\/14\/rng9GNzEhBCMUQA.png","delete":"https:\/\/sm.ms\/delete\/QChs79nUXbdZW6ygYDVOBvjGNe","page":"https:\/\/sm.ms\/image\/rng9GNzEhBCMUQA"},"RequestId":"3985A52B-A6C8-4F22-A96A-749E3C77D35E"}"

    ```
    liuxu
        10
    liuxu  
       2019-11-14 16:08:47 +08:00   1
    实际上 CURLOPT_POSTFIELDS 不需要设置 content-type 为 multipart-data

    https://www.php.net/manual/zh/function.curl-setopt.php

    CURLOPT_POSTFIELDS 全部数据使用 HTTP 协议中的 "POST" 操作来发送。 要发送文件,在文件名前面加上 @前缀并使用完整路径。 文件类型可在文件名后以 ';type=mimetype' 的格式指定。 这个参数可以是 urlencoded 后的字符串,类似'para1=val1&para2=val2&...',也可以使用一个以字段名为键值,字段数据为值的数组。 如果 value 是一个数组,Content-Type 头将会被设置成 multipart/form-data。 从 PHP 5.2.0 开始,使用 @ 前缀传递文件时,value 必须是个数组。 从 PHP 5.5.0 开始, @ 前缀已被废弃,文件可通过 CURLFile 发送。 设置 CURLOPT_SAFE_UPLOAD 为 TRUE 可禁用 @ 前缀发送文件,以增加安全性。
    Rekkles
        11
    Rekkles  
       2019-11-14 16:52:24 +08:00
    如果你用了 composer 那么请 google guzzle 的 document,
    如果没有,请使用 postman 模拟请求,成功之后 postman 可以导出代码
    完。
    mashirozx
        12
    mashirozx  
    OP
       2019-11-14 17:19:47 +08:00
    @liuxu #10 中午折腾了半天 @ 前缀,原来是和 PHP 版本有关!按您说的换了一个 UA 就成功了
    mashirozx
        13
    mashirozx  
    OP
       2019-11-14 17:23:10 +08:00
    @pota #5 中午我也看到这个帖子了,我这边是 PHP 7.2,按照 @liuxu #10 说的,不能直接那样写~ 不过还是很感谢你啦 o(* ̄ ̄*)o
    mashirozx
        14
    mashirozx  
    OP
       2019-11-14 17:25:19 +08:00
    @Rekkles #11 没用 composer~ 以后用到会注意的~
    micookie
        15
    micookie  
       2019-11-20 18:14:21 +08:00 via Android
    file_get_contens 也可以实现 post 请求,比起来变态的 curl 好多了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2899 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 13:57 PVG 21:57 LAX 06:57 JFK 09:57
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86