想用 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゜
1
pota 2019-11-14 14:04:39 +08:00
$fields = array('smfile' => "@favicon-original.png");
|
2
mashirozx OP @pota #1 试了这样的写法,但是接口返回的是资源无效。检查了 curl 的 request header,发现 ["content_type"]=> string(24) "text/html; charset=UTF-8",header 里面的 size_upload 大小好像也太小了,不像是图片,所以看起来好像图片并没有被上传,只是上传了 @favicon-original.png 几个字?萌新我不是太懂,请耐心~
|
3
young 2019-11-14 15:05:08 +08:00
|
5
pota 2019-11-14 15:20:41 +08:00
参考一下 https://stackoverflow.com/questions/15200632/how-to-upload-file-using-curl-with-php
当然说回来 你 PHP 什么版本 ? |
6
royantar 2019-11-14 15:28:00 +08:00
User-Agent 随便填一些字符试试,别用$_SERVER['HTTP_USER_AGENT']。
|
7
justfindu 2019-11-14 15:28:02 +08:00
试试文件使用绝对地址
|
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)); ``` |
9
liuxu 2019-11-14 16:04:37 +08:00
google: sm.ms 403
https://www.v2ex.com/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=UTF-8 < 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=rBWawl3NChysdVkoQsGLAg==; 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"}" ``` |
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¶2=val2&...',也可以使用一个以字段名为键值,字段数据为值的数组。 如果 value 是一个数组,Content-Type 头将会被设置成 multipart/form-data。 从 PHP 5.2.0 开始,使用 @ 前缀传递文件时,value 必须是个数组。 从 PHP 5.5.0 开始, @ 前缀已被废弃,文件可通过 CURLFile 发送。 设置 CURLOPT_SAFE_UPLOAD 为 TRUE 可禁用 @ 前缀发送文件,以增加安全性。 |
11
Rekkles 2019-11-14 16:52:24 +08:00
如果你用了 composer 那么请 google guzzle 的 document,
如果没有,请使用 postman 模拟请求,成功之后 postman 可以导出代码 完。 |
13
mashirozx OP |
15
micookie 2019-11-20 18:14:21 +08:00 via Android
file_get_contens 也可以实现 post 请求,比起来变态的 curl 好多了
|