Использование curl для загрузки данных POST с файлами
Я хотел бы использовать cURL, чтобы не только отправлять параметры данных в HTTP POST, но также загружать файлы с определенным именем формы. Как мне это сделать?
Параметры HTTP-сообщения:
userid = 12345
filecomment = Это файл изображения
Загрузка файла HTTP:
Местоположение файла =/home/user1/Desktop/test.jpg
Имя формы для файла = image (соответствует файлу $_FILES ['image'] на стороне PHP)
Я вычислил часть команды cURL следующим образом:
curl -d "userid=1&filecomment=This is an image file" --data-binary @"/home/user1/Desktop/test.jpg" localhost/uploader.php
Проблема, которую я получаю, следующая:
Notice: Undefined index: image in /var/www/uploader.php
Проблема заключается в том, что я использую $_FILES ['image'] для сбора файлов в PHP script.
Как мне настроить мои команды cURL соответственно?
Ответы
Ответ 1
Вам нужно использовать опцию -F
:
-F/--form <name=content> Specify HTTP multipart POST data (H)
Попробуйте следующее:
curl \
-F "userid=1" \
-F "filecomment=This is an image file" \
-F "[email protected]/home/user1/Desktop/test.jpg" \
localhost/uploader.php
Ответ 2
Перехват идентификатора пользователя в качестве переменной пути (рекомендуется):
curl -i -X POST -H "Content-Type: multipart/form-data"
-F "[email protected]" http://mysuperserver/media/1234/upload/
Поймать идентификатор пользователя как часть формы:
curl -i -X POST -H "Content-Type: multipart/form-data"
-F "[email protected];userid=1234" http://mysuperserver/media/upload/
или:
curl -i -X POST -H "Content-Type: multipart/form-data"
-F "[email protected]" -F "userid=1234" http://mysuperserver/media/upload/
Ответ 3
Вот мое решение, я читал много сообщений, и они были действительно полезны. Наконец, я написал код для небольших файлов, с cURL и PHP, которые, по моему мнению, действительно полезны.
public function postFile()
{
$file_url = "test.txt"; //here is the file route, in this case is on same directory but you can set URL too like "http://examplewebsite.com/test.txt"
$eol = "\r\n"; //default line-break for mime type
$BOUNDARY = md5(time()); //random boundaryid, is a separator for each param on my post curl function
$BODY=""; //init my curl body
$BODY.= '--'.$BOUNDARY. $eol; //start param header
$BODY .= 'Content-Disposition: form-data; name="sometext"' . $eol . $eol; // last Content with 2 $eol, in this case is only 1 content.
$BODY .= "Some Data" . $eol;//param data in this case is a simple post data and 1 $eol for the end of the data
$BODY.= '--'.$BOUNDARY. $eol; // start 2nd param,
$BODY.= 'Content-Disposition: form-data; name="somefile"; filename="test.txt"'. $eol ; //first Content data for post file, remember you only put 1 when you are going to add more Contents, and 2 on the last, to close the Content Instance
$BODY.= 'Content-Type: application/octet-stream' . $eol; //Same before row
$BODY.= 'Content-Transfer-Encoding: base64' . $eol . $eol; // we put the last Content and 2 $eol,
$BODY.= chunk_split(base64_encode(file_get_contents($file_url))) . $eol; // we write the Base64 File Content and the $eol to finish the data,
$BODY.= '--'.$BOUNDARY .'--' . $eol. $eol; // we close the param and the post width "--" and 2 $eol at the end of our boundary header.
$ch = curl_init(); //init curl
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'X_PARAM_TOKEN : 71e2cb8b-42b7-4bf0-b2e8-53fbd2f578f9' //custom header for my api validation you can get it from $_SERVER["HTTP_X_PARAM_TOKEN"] variable
,"Content-Type: multipart/form-data; boundary=".$BOUNDARY) //setting our mime type for make it work on $_FILE variable
);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/1.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0'); //setting our user agent
curl_setopt($ch, CURLOPT_URL, "api.endpoint.post"); //setting our api post url
curl_setopt($ch, CURLOPT_COOKIEJAR, $BOUNDARY.'.txt'); //saving cookies just in case we want
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // call return content
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1); navigate the endpoint
curl_setopt($ch, CURLOPT_POST, true); //set as post
curl_setopt($ch, CURLOPT_POSTFIELDS, $BODY); // set our $BODY
$response = curl_exec($ch); // start curl navigation
print_r($response); //print response
}
С этим мы должны попасть в "api.endpoint.post" следующие опубликованные vars. Вы можете легко протестировать этот script, и вы должны получать эти отладки в функции postFile()
в последней строке.
print_r($response); //print response
public function getPostFile()
{
echo "\n\n_SERVER\n";
echo "<pre>";
print_r($_SERVER['HTTP_X_PARAM_TOKEN']);
echo "/<pre>";
echo "_POST\n";
echo "<pre>";
print_r($_POST['sometext']);
echo "/<pre>";
echo "_FILES\n";
echo "<pre>";
print_r($_FILEST['somefile']);
echo "/<pre>";
}
Он должен работать хорошо, они могут быть лучшими решениями, но это работает, и это действительно полезно для понимания того, как MIME Boundary и multipart/from-data работают на PHP и cURL-библиотеке.
Ответ 4
если вы загружаете двоичный файл, такой как csv, используйте ниже формат для загрузки файла
curl -X POST \
'http://localhost:8080/workers' \
-H 'authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6ImFjY2VzcyIsInR5cGUiOiJhY2Nlc3MifQ.eyJ1c2VySWQiOjEsImFjY291bnRJZCI6MSwiaWF0IjoxNTExMzMwMzg5LCJleHAiOjE1MTM5MjIzODksImF1ZCI6Imh0dHBzOi8veW91cmRvbWFpbi5jb20iLCJpc3MiOiJmZWF0aGVycyIsInN1YiI6ImFub255bW91cyJ9.HWk7qJ0uK6SEi8qSeeB6-TGslDlZOTpG51U6kVi8nYc' \
-H 'content-type: application/x-www-form-urlencoded' \
--data-binary '@/home/limitless/Downloads/iRoute Masters - Workers.csv'
Ответ 5
Вот как правильно избежать произвольных имен файлов загруженных файлов с помощью bash
:
#!/bin/bash
set -eu
f="$1"
f=${f//\\/\\\\}
f=${f//\"/\\\"}
f=${f//;/\\;}
curl --silent --form "[email protected]\"$f\"" "$2"
Ответ 6
В качестве альтернативы curl
вы можете использовать HTTPie, это CLI, похожий на cURL инструмент для людей.
Инструкция по установке: https://github.com/jakubroztocil/httpie#installation
Затем запустите:
http -f POST http://localhost:4040/api/users username=johnsnow [email protected]/avatar.jpg
HTTP/1.1 200 OK
Access-Control-Expose-Headers: X-Frontend
Cache-control: no-store
Connection: keep-alive
Content-Encoding: gzip
Content-Length: 89
Content-Type: text/html; charset=windows-1251
Date: Tue, 26 Jun 2018 11:11:55 GMT
Pragma: no-cache
Server: Apache
Vary: Accept-Encoding
X-Frontend: front623311
...
Ответ 7
Проблема, которая привела меня сюда, оказалась основной ошибкой пользователя - я не включил знак @
в путь к файлу, и поэтому curl публиковал путь/имя файла, а не его содержимое. Поэтому значение Content-Length
было 8, а не 479, которые я ожидал увидеть, учитывая длину моего тестового файла.
Заголовок Content-Length
будет автоматически рассчитан, когда curl читает и публикует файл.
curl -i -H "Content-Type: application/xml" --data "@test.xml" -v -X POST https://<url>/<uri/
...
& Lt; Длина контента: 479
...
Размещение этого здесь, чтобы помочь другим новичкам в будущем.
Ответ 8
Официальная библиотека PHP Vimeo предоставляет загрузчик командной строки, который использует значительно более стабильный рабочий процесс загрузки.
Файл находится здесь: https://github.com/vimeo/vimeo.php/blob/master/example/upload.php и вам нужно создать файл config.json, подобный этому: https://github.com/vimeo/vimeo.php/blob/master/example/config.json.example с вашим токеном доступа.
После настройки вы можете загрузить видео с помощью php upload.php ~/video.mp4