Chiama un'API REST in PHP


317

Il nostro cliente mi ha fornito un'API REST a cui devo effettuare una chiamata PHP. Ma in realtà la documentazione fornita con l'API è molto limitata, quindi non so davvero come chiamare il servizio.

Ho provato a cercarlo su Google, ma l'unica cosa che è venuta fuori è stata una Yahoo già scaduta! tutorial su come chiamare il servizio. Per non parlare delle intestazioni o di qualsiasi informazione approfondita.

Esistono informazioni decenti su come chiamare un'API REST o sulla documentazione a riguardo? Perché anche su W3schools, descrivono solo il metodo SOAP. Quali sono le diverse opzioni per rendere API di riposo in PHP?

Risposte:


438

Puoi accedere a qualsiasi API REST con l' cURLestensione PHPs . Tuttavia, la documentazione API (metodi, parametri ecc.) Deve essere fornita dal cliente!

Esempio:

// 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: il metodo di richiesta HTTP (GET, POST, PUT ecc.). A seconda dell'API, sono richiesti diversi metodi. vale a dire OTTENERE per la lettura, POST per la scrittura.
Christoph Winkler,

2
@Michiel $dataè un array associativo (data [fieldname] = value) che contiene i dati inviati al metodo api.
Christoph Winkler,

1
Grazie per la tua grande assistenza!
Michiel,

2
Nota, la curl_closefunzione non viene chiamata, cosa potrebbe causare un ulteriore consumo di memoria se la funzione CallAPI viene chiamata ripetutamente.
Bart Verkoeijen,

1
La risposta di @colan di seguito è decisamente migliore: ti fa risparmiare tutta la seccatura con la creazione dei tuoi metodi di gestione degli errori e del wrapper.
Andreas,

186

Se hai un URL e il tuo php lo supporta, puoi semplicemente chiamare file_get_contents:

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

se $ response è JSON, utilizzare json_decode per trasformarlo in array php:

$response = json_decode($response);

se $ response è XML, utilizzare la classe simple_xml:

$response = new SimpleXMLElement($response);

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


30
Se l'endpoint REST restituisce uno stato di errore HTTP (ad es. 401), la file_get_contentsfunzione ha esito negativo con un avviso e restituisce null. Se il corpo contiene un messaggio di errore, non è possibile recuperarlo.
Bart Verkoeijen,

3
Il suo principale svantaggio è che l'installazione PHP deve avere wrapper fopen abilitato per accedere agli URL. Se i wrapper fopen non sono abilitati, non sarà possibile utilizzare file_get_contents per le richieste dei servizi Web.
Oriol,

2
i wrapper fopen sono tra le parti di PHP ora viste come vulnerabilità, quindi è probabile che alcuni host lo disabilitino.
Marcus Downing,

153

Usa Guzzle . È un "client HTTP PHP che semplifica il lavoro con HTTP / 1.1 e risolve i problemi legati al consumo di servizi Web". Lavorare con Guzzle è molto più semplice che lavorare con cURL.

Ecco un esempio dal sito 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

20
Chiunque stia ancora usando cURL non ha mai dato un'occhiata da vicino a questa opzione.
JoshuaDavid,

Sembra carino. Ma per quanto riguarda il recupero di PNG? Per tessere mappa. Posso trovare solo i dati JSON menzionati nella pagina Web che hai collegato.
Henrik Erlandsson,

20

CURL è il modo più semplice di procedere. Ecco una semplice chiamata

$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
bene @ erm3nda L'OP sta dicendo "quindi non so davvero come chiamare il servizio" NON Trovarmi il modo migliore per consumare un API REST.
Broncha,

4
wow, sprechi il tuo sforzo e il tuo tempo per farmi una risposta ironica invece di rendere migliore il tuo commento. Buona fortuna in quel modo.
m3nda,

2
Adoro quanto sia semplice questo. Continuate così
cyber8200,

@Sadik POST DATA è solo un segnaposto, dovrai inviare i tuoi dati postali lì
Broncha,

12

Usa HTTPFUL

Httpful è una libreria PHP semplice, concatenabile e leggibile, progettata per rendere sano parlare HTTP. Consente allo sviluppatore di interagire con le API invece di setacciare le pagine set_opt di arricciatura ed è un client PHP REST ideale.

Httpful include ...

  • Supporto del metodo HTTP leggibile (GET, PUT, POST, DELETE, HEAD e OPTIONS)
  • Intestazioni personalizzate
  • Analisi "intelligente" automatica
  • Serializzazione automatica del payload
  • Aut. Base
  • Autenticazione certificato lato client
  • Richiedi "Modelli"

Ex.

Invia una richiesta GET. Ottieni una risposta JSON analizzata automaticamente.

La libreria rileva il tipo di contenuto JSON nella risposta e analizza automaticamente la risposta in un oggetto PHP nativo.

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

Sto cercando di utilizzare HTTPFUL come soluzione e non sono sicuro che possa analizzare JSON come $condition = $response->weather[0]->main;se non sto sbagliando la parte PHP
weteamsteve

9

Dovrai sapere se l'API REST che stai chiamando supporta GETo POSTo entrambi i metodi. Il codice qui sotto è qualcosa che funziona per me, sto chiamando la mia API del servizio web, quindi so già cosa prende l'API e cosa restituirà. Supporta entrambi GETe POSTmetodi, quindi le informazioni meno sensibili vanno in URL (GET), e le informazioni come nome utente e password vengono inviate come POSTvariabili. Inoltre, tutto va oltre la HTTPSconnessione.

All'interno del codice API, codifico un array che voglio tornare nel formato json, quindi uso semplicemente il comando PHP echo $my_json_variableper rendere quella stringa json disponibile al client.

Come puoi vedere, la mia API restituisce dati json, ma devi sapere (o guardare i dati restituiti per scoprire) in quale formato è la risposta dall'API.

Ecco come mi collego all'API dal lato 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;
}

A proposito, ho anche provato a usare il file_get_contents()metodo come suggerito da alcuni degli utenti, ma non funziona bene per me. Ho scoperto che il curlmetodo è più veloce e più affidabile.


5

In realtà ci sono molti clienti. Uno di questi è Pest : dai un'occhiata a questo. E tieni presente che queste chiamate REST sono semplici richieste http con vari metodi: GET, POST, PUT e DELETE.


4

È possibile utilizzare file_get_contentsper emettere qualsiasi POST/PUT/DELETE/OPTIONS/HEADmetodo http , oltre al GETmetodo come suggerisce il nome della funzione.

Come pubblicare dati in PHP usando file_get_contents?


1
file_get_content è davvero una cattiva idea quando si tratta di API. stackoverflow.com/questions/13004805/… Puoi impostare un metodo personalizzato come file_get_contents_curl e usarlo al posto della semplice soluzione php. stackoverflow.com/questions/8540800/…
Eryk Wróbel

3

Se stai usando Symfony c'è un ottimo pacchetto client di riposo che include anche tutte le ~ 100 eccezioni e le lancia invece di restituire un codice di errore + messaggio insignificante.

Dovresti davvero verificarlo: https://github.com/CircleOfNice/CiRestClientBundle

Adoro l'interfaccia:

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

Funziona con tutti i metodi http.


2

come @Christoph Winkler ha menzionato questa è una classe base per raggiungerla:

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

}

Quindi puoi sempre includere il file e usarlo, ad esempio: 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

Se sei aperto a utilizzare strumenti di terze parti, dai un'occhiata a questo: https://github.com/CircleOfNice/DoctrineRestDriver

Questo è un modo completamente nuovo di lavorare con le API.

Prima di tutto devi definire un'entità che sta definendo la struttura dei dati in entrata e in uscita e annotarla con origini dati:

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

Ora è abbastanza facile comunicare con 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();

-1

Puoi andare con POSTMAN, un'applicazione che semplifica le API. Compila i campi di richiesta e quindi genererà il codice per te in diverse lingue. Basta fare clic sul codice sul lato destro e selezionare la lingua preferita.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.