Вызовите REST API в PHP

317

Наш клиент дал мне REST API, к которому мне нужно обратиться с помощью PHP. Но на самом деле документация, предоставляемая с API, очень ограничена, поэтому я не знаю, как вызвать сервис.

Я попытался Google это, но единственное, что подошло, было уже просроченным Yahoo! учебник о том, как позвонить в службу. Не говоря уже о заголовках или что-то в глубине информации

Есть ли приличная информация о том, как вызывать REST API, или какая-то документация по этому поводу? Потому что даже в W3schools они описывают только метод SOAP. Какие есть варианты для создания API отдыха в PHP?

Михель
источник

Ответы:

438

Вы можете получить доступ к любому REST API с cURLрасширением PHPs . Однако документация API (методы, параметры и т. Д.) Должна быть предоставлена ​​вашим клиентом!

Пример:

// Method: POST, PUT, GET etc
// Data: array("param" => "value") ==> index.php?param=value

function CallAPI($method, $url, $data = false)
{
    $curl = curl_init();

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    // Optional Authentication:
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($curl, CURLOPT_USERPWD, "username:password");

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}
Кристоф Винклер
источник
1
@Michiel: метод HTTP-запроса (GET, POST, PUT и т. Д.). В зависимости от API требуются разные методы. т.е. ПОЛУЧИТЕ для чтения, ПОЧТУ для записи.
Кристоф Винклер
2
@Michiel $data- это ассоциативный массив (data [fieldname] = value), в котором хранятся данные, отправленные в метод api.
Кристоф Винклер
1
Спасибо за вашу большую помощь!
Михель
2
Обратите внимание, что curl_closeфункция не вызывается, что может вызвать дополнительное потребление памяти, если функция CallAPI вызывается повторно.
Барт Verkoeijen
1
Ответ от @colan ниже гораздо лучше - он избавит вас от хлопот, связанных с созданием собственных методов обработки ошибок и обертки.
Андреас
186

Если у вас есть URL и ваш php поддерживает его, вы можете просто вызвать file_get_contents:

$response = file_get_contents('http://example.com/path/to/api/call?param1=5');

если $ response - JSON, используйте json_decode, чтобы превратить его в массив php:

$response = json_decode($response);

если $ response является XML, используйте класс simple_xml:

$response = new SimpleXMLElement($response);

http://sg2.php.net/manual/en/simplexml.examples-basic.php

Андреас Вонг
источник
30
Если конечная точка REST возвращает статус ошибки HTTP (например, 401), file_get_contentsфункция завершается с ошибкой и возвращает ноль. Если тело содержит сообщение об ошибке, вы не можете получить его.
Барт Verkoeijen
3
Его главный недостаток заключается в том, что в вашей установке PHP должны быть включены обертки fopen для доступа к URL-адресам. Если fopen wrappers не включен, вы не сможете использовать file_get_contents для запросов веб-сервисов.
Oriol
2
Оболочки fopen входят в число уязвимостей PHP, поэтому некоторые хосты могут отключить их.
Маркус Даунинг
153

Используйте Жадность . Это «PHP HTTP-клиент, который облегчает работу с HTTP / 1.1 и избавляет от необходимости использовать веб-сервисы». Работать с Guzzle намного проще, чем с cURL.

Вот пример с веб-сайта:

$client = new GuzzleHttp\Client();
$res = $client->get('https://api.github.com/user', [
    'auth' =>  ['user', 'pass']
]);
echo $res->getStatusCode();           // 200
echo $res->getHeader('content-type'); // 'application/json; charset=utf8'
echo $res->getBody();                 // {"type":"User"...'
var_export($res->json());             // Outputs the JSON decoded data
Колан
источник
20
Тот, кто все еще использует cURL, никогда не рассматривал эту опцию внимательно.
Джошуа Дэвид
Кажется, хорошо. Но как насчет получения PNG? Для тайлов карты. Я могу найти только данные JSON, упомянутые на веб-странице, на которую вы ссылаетесь.
Хенрик Эрландссон
20

CURL - это самый простой способ. Вот простой звонок

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "THE URL TO THE SERVICE");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, POST DATA);
$result = curl_exec($ch);


print_r($result);
curl_close($ch);
Broncha
источник
1
well @ erm3nda ОП говорит "поэтому я не знаю, как позвонить в службу". НЕ Дайте мне лучший способ использовать REST API.
Бронча
4
вау, ты тратишь свои усилия и время на то, чтобы вместо этого поставить мне ироничный ответ, чтобы сделать твой комментарий лучше. Удачи в этом смысле.
m3nda
2
Люблю, как это просто. Так держать
cyber8200
@Sadik POST DATA - это просто заполнитель, вам нужно будет отправить туда свои почтовые данные
Бронча
12

Используйте HTTPFUL

Httpful - это простая, читабельная, читаемая PHP-библиотека, предназначенная для того, чтобы говорить по HTTP нормально. Он позволяет разработчику сосредоточиться на взаимодействии с API-интерфейсами, а не на просмотре страниц curl set_opt, и является идеальным клиентом PHP REST.

Httpful включает в себя ...

  • Поддержка читаемых методов HTTP (GET, PUT, POST, DELETE, HEAD и OPTIONS)
  • Пользовательские Заголовки
  • Автоматический «умный» парсинг
  • Автоматическая сериализация полезной нагрузки
  • Basic Auth
  • Проверка подлинности сертификата на стороне клиента
  • Запрос "Шаблоны"

Ex.

Отправьте запрос GET. Получите автоматически проанализированный JSON-ответ.

Библиотека замечает JSON Content-Type в ответе и автоматически анализирует ответ в нативный объект PHP.

$uri = "https://www.googleapis.com/freebase/v1/mqlread?query=%7B%22type%22:%22/music/artist%22%2C%22name%22:%22The%20Dead%20Weather%22%2C%22album%22:%5B%5D%7D";
$response = \Httpful\Request::get($uri)->send();

echo 'The Dead Weather has ' . count($response->body->result->album) . " albums.\n";
Сомнат Мулук
источник
Я пытаюсь использовать HTTPFUL в качестве решения, и я не уверен, что он может анализировать json, как $condition = $response->weather[0]->main;если бы я просто не делал сторону PHP неправильно
weteamsteve
9

Вы должны знать , если REST API вы вызываете поддерживает GETили POST, или оба метода. Приведенный ниже код работает для меня, я называю свой собственный API веб-службы, поэтому я уже знаю, что API берет и что он вернет. Он поддерживает оба метода GETи POSTметоды, поэтому менее важная информация попадает в URL (GET), а информация, такая как имя пользователя и пароль, представляется в виде POSTпеременных. Кроме того, все идет по HTTPSсвязи.

Внутри кода API я кодирую массив, который хочу вернуть, в формате json, а затем просто использую команду PHP, echo $my_json_variableчтобы сделать эту строку json доступной для клиента.

Итак, как вы можете видеть, мой API возвращает данные json, но вам нужно знать (или посмотреть на возвращенные данные, чтобы выяснить), в каком формате находится ответ от API.

Вот как я подключаюсь к API со стороны клиента:

$processed = FALSE;
$ERROR_MESSAGE = '';

// ************* Call API:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.myapi.com/api.php?format=json&action=subscribe&email=" . $email_to_subscribe);
curl_setopt($ch, CURLOPT_POST, 1);// set post data to true
curl_setopt($ch, CURLOPT_POSTFIELDS,"username=myname&password=mypass");   // post data
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$json = curl_exec($ch);
curl_close ($ch);

// returned json string will look like this: {"code":1,"data":"OK"}
// "code" may contain an error code and "data" may contain error string instead of "OK"
$obj = json_decode($json);

if ($obj->{'code'} == '1')
{
  $processed = TRUE;
}else{
  $ERROR_MESSAGE = $obj->{'data'};
}

...

if (!$processed && $ERROR_MESSAGE != '') {
    echo $ERROR_MESSAGE;
}

Кстати, я также пытался использовать file_get_contents()метод, как предлагали некоторые из пользователей, но он мне не помог. Я обнаружил, что curlметод быстрее и надежнее.

Дерек Гоголь
источник
5

На самом деле клиентов много. Одним из них является Пешт - проверьте это. И имейте в виду, что эти вызовы REST являются простым http-запросом с различными методами: GET, POST, PUT и DELETE.

deadrunk
источник
4

Вы можете использовать file_get_contentsдля выдачи любые POST/PUT/DELETE/OPTIONS/HEADметоды http , в дополнение к GETметоду, как предполагает название функции.

Как разместить данные в PHP с помощью file_get_contents?

Чуан Ма
источник
1
file_get_content - очень плохая идея, когда дело доходит до API. stackoverflow.com/questions/13004805/… Вы можете установить собственный метод, например file_get_contents_curl, и использовать его вместо простого решения php.stackoverflow.com/questions/8540800/…
Эрик Врубель
3

Если вы используете Symfony, есть отличный клиентский пакет отдыха, который даже включает все ~ 100 исключений и выдает их вместо того, чтобы возвращать какой-то бессмысленный код ошибки + сообщение.

Вы должны действительно проверить это: https://github.com/CircleOfNice/CiRestClientBundle

Я люблю интерфейс:

try {
    $restClient = new RestClient();
    $response   = $restClient->get('http://www.someUrl.com');
    $statusCode = $response->getStatusCode();
    $content    = $response->getContent();
} catch(OperationTimedOutException $e) {
    // do something
}

Работает для всех методов http.

Тобиас
источник
2

как заметил @Christoph Winkler, это базовый класс для его достижения:

curl_helper.php

// This class has all the necessary code for making API calls thru curl library

class CurlHelper {

// This method will perform an action/method thru HTTP/API calls
// Parameter description:
// Method= POST, PUT, GET etc
// Data= array("param" => "value") ==> index.php?param=value
public static function perform_http_request($method, $url, $data = false)
{
    $curl = curl_init();

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            break;
        case "PUT":
            curl_setopt($curl, CURLOPT_PUT, 1);
            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    // Optional Authentication:
    //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    //curl_setopt($curl, CURLOPT_USERPWD, "username:password");

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}

}

Тогда вы всегда можете включить файл и использовать его, например: any.php

    require_once("curl_helper.php");
    ...
    $action = "GET";
    $url = "api.server.com/model"
    echo "Trying to reach ...";
    echo $url;
    $parameters = array("param" => "value");
    $result = CurlHelper::perform_http_request($action, $url, $parameters);
    echo print_r($result)
d1jhoni1b
источник
0

Если вы открыты для использования сторонних инструментов, посмотрите на это: https://github.com/CircleOfNice/DoctrineRestDriver

Это совершенно новый способ работы с API.

Прежде всего вы определяете сущность, которая определяет структуру входящих и исходящих данных, и аннотируете ее источниками данных:

/*
 * @Entity
 * @DataSource\Select("http://www.myApi.com/products/{id}")
 * @DataSource\Insert("http://www.myApi.com/products")
 * @DataSource\Select("http://www.myApi.com/products/update/{id}")
 * @DataSource\Fetch("http://www.myApi.com/products")
 * @DataSource\Delete("http://www.myApi.com/products/delete/{id}")
 */
class Product {
    private $name;

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

Теперь довольно просто общаться с REST API:

$product = new Product();
$product->setName('test');
// sends an API request POST http://www.myApi.com/products ...
$em->persist($product);
$em->flush();

$product->setName('newName');
// sends an API request UPDATE http://www.myApi.com/products/update/1 ...
$em->flush();
Тобиас
источник
-1

Вы можете использовать POSTMAN, приложение, которое упрощает API. Заполните поля запроса, и он сгенерирует для вас код на разных языках. Просто нажмите код справа и выберите нужный язык.

Xhuljo
источник