Виклик API REST в PHP


317

Наш клієнт дав мені API REST, на який мені потрібно зробити дзвінок PHP. Але насправді документація, надана в API, дуже обмежена, тому я не знаю, як викликати службу.

Я спробував це в Google, але єдине, що з’явилося, це вже закінчений термін Yahoo! підручник про те, як зателефонувати в службу. Не згадуючи заголовків чи нічого глибокої інформації.

Чи є якась гідна інформація щодо того, як викликати API REST, чи якусь документацію про нього? Тому що навіть у W3schools вони описують лише метод SOAP. Які існують варіанти створення API відпочинку в PHP?

Відповіді:


438

Ви можете отримати доступ до будь-якого REST API з cURLрозширенням PHP . Однак, Документацію 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 потрібні різні методи. тобто GET для читання, POST для письма.
Крістоф Вінклер

2
@Michiel $data- це асоціативний масив (data [fieldname] = значення), який містить дані, надіслані методу api.
Крістоф Вінклер

1
Дякуємо за велику допомогу!
Міхель

2
Зауважте, curl_closeфункція не викликається, що може спричинити додаткове споживання пам'яті, якщо функція CallAPI викликається повторно.
Барт Веркойейн

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функція не працює з попередженням і повертає нуль. Якщо тіло містить повідомлення про помилку, ви не можете його отримати.
Барт Веркойейн

3
Основним його недоліком є ​​те, що у вашій установці PHP повинні бути включені обгортки фопенд для доступу до URL-адрес. Якщо обгортки фопенд не ввімкнено, ви не зможете використовувати file_get_contents для запитів веб-служб.
Оріол

2
обгортки fopen є частиною PHP, яка зараз сприймається як вразливість, тому ви, ймовірно, побачите, що деякі хости відключили його.
Маркус Даунінг

153

Використовуйте Guzzle . Це "PHP-клієнт PHP, який спрощує роботу з 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, ніколи не пильно розглядав цей варіант.
JoshuaDavid

Здається приємно. Але як щодо отримання 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);

1
добре @ erm3nda В ОП говорять "так що я не знаю, як зателефонувати в службу".
Бронча

4
уау, ви витрачаєте свої зусилля та час, щоб замість цього зробити мені іронічну відповідь, щоб зробити ваш коментар кращим. Удачі в цьому.
м3нда

2
Полюби, як це просто. Продовжуйте
cyber8200

@Sadik POST DATA - лише власник місця, вам потрібно буде надіслати свої поштові дані туди
Broncha

12

Використовуйте HTTPFUL

Httpful - це проста, зручна для читання бібліотека PHP, призначена зробити розмову HTTP здоровою. Це дозволяє розробнику зосередитись на взаємодії з API, а не на просіюванні сторінок curl set_opt і є ідеальним клієнтом PHP REST.

Httpful включає ...

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

Вих.

Надішліть GET-запит. Отримати автоматично проаналізовану відповідь JSON.

Бібліотека помічає у відповіді тип вмісту JSON і автоматично аналізує відповідь на нативний об'єкт 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.


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/…
Eryk Wróbel

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)

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;
    }
}

Тепер досить просто спілкуватися з API REST:

$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. Заповніть поля запиту, і тоді він генерує код для вас на різних мовах. Просто натисніть код праворуч і виберіть бажану мову.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.