У меня есть задача получить данные из API, используя PHP. Он использует POST запрос, который также отправляет json body. Там нет упоминания о настройке каких-либо заголовков, что меня смутило. Я имел дело с использованием API ajax раньше, никогда php. И поскольку json идет в обе стороны, к API и в ответ от API, я немного запутался.
Я пытался делать это ванильным php способом, но на разных постах на SO говорится, что это не рекомендуется. Многие говорили, что использование cURL является правильным способом, поэтому я предполагаю, что это правильный путь без привлечения сторонних библиотек, которые я (также) не могу использовать в этом случае.
Мой код:
Json тело:
$str = '{"username":"mymail@mymail.com","password":"blah"}';
//or
$arr = [
"username" => "mymail@mymail.com",
"password" => "blah"
];
function post1($url,$data){
$ch = curl_init();
//Example1
curl_setopt($ch, CURLOPT_HEADER, false);
$query = http_build_query($data);
//curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type" => "application/json"]);
//Alt header for Example2
//curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
$query = $data;
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $query);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
//Example1
//echo post1($url1,$str);
//VS
//Example2
echo post1($url1,$arr);
И пример json и не json выдают одну и ту же ошибку:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.13","title":"Unsupported Media Type","status":415,"traceId":"80002328-0002-ff00-b63f-84710c7967bb"}
Если я использую альтернативный заголовок для example2, он выдаст другой:
{"errors":{"":["Input string '--------------------------7abe186689ac2978' is not a valid number. Path '', line 1, position 42."]},"title":"One or more validation errors occurred.","status":400,"traceId":"8000232a-0002-ff00-b63f-84710c7967bb"}
В имеющемся у меня документе API нет упоминания об установке каких-либо заголовков, тем не менее, я попытался даже установить заголовки , Оба способа не сработали. Просто выдает ошибку. Так что либо я что-то упустил в cURL, либо они прислали мне неполную документацию. В любом случае, я не уверен, так как я никогда не использовал cURL, и я никогда не использовал этот API.
Я также пробовал это в Почтальоне, с заголовками и без, я даже пытался установить json тело с кавычками (это глупо, я знаю), просто чтобы исключить любые возможности. Ничего из этого не сработало.
Заранее благодарен всем добрым людям, которые могут предложить мне решение на основе ранее изложенного или, по крайней мере, указали мне в правильном направлении.
Edit1: Пробовал подход Брайана с заголовками, остальной код мой.
function post2($url,$data){
$headers = array(
"Accept-Encoding: gzip",
"Content-Type: application/json"
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
//$query = $data;
$query = http_build_query($data);
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS, $query);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
Я попробовал 4 варианта этого. 1. Данные в виде массива и $query = $data;
. Ошибка:
{"errors":{"":["Input string '--------------------------ae9f656894b99247' is not a valid number. Path '', line 1, position 42."]},"title":"One or more validation errors occurred.","status":400,"traceId":"80002dd0-0002-fe00-b63f-84710c7967bb"}
Данные в виде строки и
$query = $data;
. Ошибка:
Internal server error
Данные в виде массива и
$query = http_build_query($data);
. Ошибка:
{"errors":{"":["Unexpected character encountered while parsing value: k. Path '', line 0, position 0."]},"title":"One or more validation errors occurred.","status":400,"traceId":"80002dd2-0002-fe00-b63f-84710c7967bb"}
Данные в виде строки и
$query = http_build_query($data);
. Ошибка:
Warning: http_build_query(): Parameter 1 expected to be Array or Object. Incorrect value given in C:\xampp\htdocs\xmlovi\test1.php on line 56
{"errors":{"":["A non-empty request body is required."]},"title":"One or more validation errors occurred.","status":400,"traceId":"800022db-0002-f700-b63f-84710c7967bb"}
Edit2: Если я использую Postman
с заголовком json: Ошибка:
Internal server error
Если я использую Postman
без json заголовок: Ошибка:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.13",
"title": "Unsupported Media Type",
"status": 415,
"traceId": "80002dda-0002-fe00-b63f-84710c7967bb"
}
Edit3:
Хорошо, я попробовал свой оригинальный код с проверенным API (репо) который я сделал сам Оба варианта исходного кода хороши, будь то json или пример параметров запроса. Мой API тестируется с использованием стандартных ajax (jquery и vanilla js), почтальона и теперь даже cURL от PHP. Readme.md в нем довольно многословен и пункты в нем легко проверяются.