Получить данные из API, используя PHP - PullRequest
0 голосов
/ 21 марта 2020

У меня есть задача получить данные из 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 в нем довольно многословен и пункты в нем легко проверяются.

1 Ответ

0 голосов
/ 21 марта 2020

ОБНОВЛЕНИЕ

Хорошо, давайте пока удалим заголовки, поскольку это не помогло.

Я добавил в Expect: в httpheader, потому что некоторые веб это нужно серверам при использовании post согласно комментариям на curl_setopt

Вы уже пытались отправить строку запроса внутри массива? (см. ниже)

function post1($url,$data){

    $ch = curl_init();

    //Example1
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_HTTPHEADER,array("Expect:"));

    $query = http_build_query($data, '', '&');

    curl_setopt($ch,CURLOPT_URL, $url);

    curl_setopt($ch,CURLOPT_POSTFIELDS, array($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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...