Appeler une API REST en PHP

317

Notre client m'avait donné une API REST à laquelle je dois appeler PHP. Mais en fait, la documentation fournie avec l'API est très limitée, donc je ne sais pas vraiment comment appeler le service.

J'ai essayé de Google, mais la seule chose qui est apparue était un Yahoo! déjà expiré tutoriel sur la façon d'appeler le service. Sans mentionner les en-têtes ou quoi que ce soit dans les informations détaillées.

Existe-t-il des informations décentes sur la façon d'appeler une API REST ou une documentation à ce sujet? Parce que même sur W3schools, ils ne décrivent que la méthode SOAP. Quelles sont les différentes options pour créer une API de repos en PHP?

Michiel
la source

Réponses:

438

Vous pouvez accéder à n'importe quelle API REST avec l' cURLextension PHP . Cependant, la documentation de l'API (méthodes, paramètres, etc.) doit être fournie par votre client!

Exemple:

// 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;
}
Christoph Winkler
la source
1
@Michiel: La méthode de requête HTTP (GET, POST, PUT etc.). Selon l'API, différentes méthodes sont requises. ie GET pour la lecture, POST pour l'écriture.
Christoph Winkler
2
@Michiel $dataest un tableau associatif (data [fieldname] = value) qui contient les données envoyées à la méthode api.
Christoph Winkler
1
Merci pour votre grande assistance!
Michiel
2
Notez que la curl_closefonction n'est pas appelée, ce qui pourrait entraîner une consommation de mémoire supplémentaire si la fonction CallAPI est appelée à plusieurs reprises.
Bart Verkoeijen
1
La réponse de @colan ci-dessous est bien meilleure - cela vous évite d'avoir à créer vos propres méthodes de gestion des erreurs et de wrapper.
Andreas
186

Si vous avez une URL et que votre php la prend en charge, vous pouvez simplement appeler file_get_contents:

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

si $ response est JSON, utilisez json_decode pour le transformer en tableau php:

$response = json_decode($response);

si $ response est XML, utilisez la classe simple_xml:

$response = new SimpleXMLElement($response);

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

Andreas Wong
la source
30
Si le point de terminaison REST renvoie un état d'erreur HTTP (par exemple 401), la file_get_contentsfonction échoue avec un avertissement et renvoie null. Si le corps contient un message d'erreur, vous ne pouvez pas le récupérer.
Bart Verkoeijen
3
Son principal inconvénient est que votre installation PHP doit avoir des wrappers fopen activés pour accéder aux URL. Si les wrappers fopen ne sont pas activés, vous ne pourrez pas utiliser file_get_contents pour les demandes de services Web.
Oriol
2
Les wrappers fopen font partie des parties de PHP désormais considérées comme une vulnérabilité, vous verrez donc probablement certains hôtes le désactiver.
Marcus Downing
153

Utilisez Guzzle . Il s'agit d'un "client PHP PHP qui facilite le travail avec HTTP / 1.1 et évite la consommation de services Web". Travailler avec Guzzle est beaucoup plus facile que de travailler avec cURL.

Voici un exemple tiré du site Web:

$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
colan
la source
20
Quiconque utilise encore cURL n'a jamais examiné de près cette option.
JoshuaDavid
Ça a l'air bien. Mais qu'en est-il de la récupération des fichiers PNG? Pour les tuiles de carte. Je ne peux trouver que les données JSON mentionnées sur la page Web que vous avez liée.
Henrik Erlandsson
20

CURL est la façon la plus simple de procéder. Voici un simple appel

$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
la source
1
bien @ erm3nda L'OP dit "donc je ne sais pas vraiment comment appeler le service" PAS Obtenez-moi la meilleure façon de consommer une api REST.
Broncha
4
wow, vous perdez vos efforts et votre temps à me mettre une réponse ironique à la place pour améliorer votre commentaire. Bonne chance de cette façon.
m3nda
2
J'adore la simplicité de celui-ci. Continuez comme ça
cyber8200
@Sadik POST DATA n'est qu'un espace réservé, vous devrez y envoyer vos données de poste
Broncha
12

Utilisez HTTPFUL

Httpful est une bibliothèque PHP simple, chaînable et lisible destinée à rendre le langage HTTP sain d'esprit. Il permet au développeur de se concentrer sur l'interaction avec les API au lieu de parcourir les pages curl set_opt et est un client PHP REST idéal.

Httpful comprend ...

  • Prise en charge des méthodes HTTP lisibles (GET, PUT, POST, DELETE, HEAD et OPTIONS)
  • En-têtes personnalisés
  • Analyse automatique "intelligente"
  • Sérialisation automatique de la charge utile
  • Authentification de base
  • Authentification du certificat côté client
  • Demander des "modèles"

Ex.

Envoyez une demande GET. Obtenez une réponse JSON automatiquement analysée.

La bibliothèque remarque le type de contenu JSON dans la réponse et analyse automatiquement la réponse dans un objet PHP natif.

$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";
Somnath Muluk
la source
J'essaie d'utiliser HTTPFUL comme solution et je ne suis pas sûr qu'il puisse analyser le json comme à $condition = $response->weather[0]->main;moins que je fasse juste du mauvais côté PHP
weteamsteve
9

Vous aurez besoin de savoir si l'API REST que vous appelez des supports GETou POST, ou les deux méthodes. Le code ci-dessous est quelque chose qui fonctionne pour moi, j'appelle ma propre API de service Web, donc je sais déjà ce que l'API prend et ce qu'elle renverra. Il prend en charge les méthodes GETet POST, de sorte que les informations moins sensibles entrent dans le URL (GET), et les informations telles que le nom d'utilisateur et le mot de passe sont soumises en tant que POSTvariables. De plus, tout passe par la HTTPSconnexion.

Dans le code API, j'encode un tableau que je veux retourner au format json, puis j'utilise simplement la commande PHP echo $my_json_variablepour rendre cette chaîne json disponible pour le client.

Donc, comme vous pouvez le voir, mon API renvoie des données json, mais vous devez savoir (ou regarder les données renvoyées pour savoir) dans quel format est la réponse de l'API.

Voici comment je me connecte à l'API du côté client:

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

BTW, j'ai également essayé d'utiliser la file_get_contents()méthode comme certains des utilisateurs ici l'ont suggéré, mais cela ne fonctionne pas bien pour moi. J'ai découvert que la curlméthode était plus rapide et plus fiable.

Derek Gogol
la source
5

Il y a en fait beaucoup de clients. L'un d'eux est Pest - vérifiez cela. Et gardez à l'esprit que ces appels REST sont de simples requêtes http avec différentes méthodes: GET, POST, PUT et DELETE.

impasse
la source
4

Vous pouvez utiliser file_get_contentspour émettre n'importe quelle POST/PUT/DELETE/OPTIONS/HEADméthode http , en plus de la GETméthode comme le suggère le nom de la fonction.

Comment publier des données en PHP en utilisant file_get_contents?

Chuan Ma
la source
1
file_get_content est vraiment une mauvaise idée en ce qui concerne l'API. stackoverflow.com/questions/13004805/… Vous pouvez définir une méthode personnalisée comme file_get_contents_curl et l'utiliser à la place d'une solution php standard. stackoverflow.com/questions/8540800/…
Eryk Wróbel
3

Si vous utilisez Symfony, il existe un excellent ensemble de clients de repos qui comprend même toutes les ~ 100 exceptions et les jette au lieu de renvoyer un code d'erreur + un message sans signification.

Vous devriez vraiment le vérifier: https://github.com/CircleOfNice/CiRestClientBundle

J'adore l'interface:

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

Fonctionne pour toutes les méthodes http.

Tobias
la source
2

comme @Christoph Winkler l'a mentionné, il s'agit d'une classe de base pour y parvenir:

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

}

Ensuite, vous pouvez toujours inclure le fichier et l'utiliser, par exemple: 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
la source
0

Si vous êtes ouvert à l'utilisation d'outils tiers, vous devriez jeter un œil à celui-ci: https://github.com/CircleOfNice/DoctrineRestDriver

Il s'agit d'une toute nouvelle façon de travailler avec les API.

Tout d'abord, vous définissez une entité qui définit la structure des données entrantes et sortantes et vous les annotez avec des sources de données:

/*
 * @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;
    }
}

Il est maintenant assez facile de communiquer avec l'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();
Tobias
la source
-1

Vous pouvez opter pour POSTMAN, une application qui facilite les API. Remplissez les champs de demande, puis il générera pour vous du code dans différentes langues. Cliquez simplement sur le code sur le côté droit et sélectionnez votre langue préférée.

Xhuljo
la source