Rufen Sie eine REST-API in PHP auf

317

Unser Kunde hatte mir eine REST-API gegeben, bei der ich einen PHP-Aufruf durchführen muss. Tatsächlich ist die mit der API bereitgestellte Dokumentation jedoch sehr begrenzt, sodass ich nicht wirklich weiß, wie ich den Dienst aufrufen soll.

Ich habe versucht, es zu googeln, aber das einzige, was auftauchte, war ein bereits abgelaufenes Yahoo! Tutorial zum Aufrufen des Dienstes. Ganz zu schweigen von den Überschriften oder detaillierten Informationen.

Gibt es anständige Informationen zum Aufrufen einer REST-API oder eine Dokumentation dazu? Denn auch in W3-Schulen wird nur die SOAP-Methode beschrieben. Welche verschiedenen Optionen gibt es, um eine Rest-API in PHP zu erstellen?

Michiel
quelle

Antworten:

438

Sie können mit der PHPs- cURLErweiterung auf jede REST-API zugreifen . Die API-Dokumentation (Methoden, Parameter usw.) muss jedoch von Ihrem Kunden bereitgestellt werden!

Beispiel:

// 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
quelle
1
@Michiel: Die HTTP-Anforderungsmethode (GET, POST, PUT usw.). Abhängig von der API sind unterschiedliche Methoden erforderlich. dh GET zum Lesen, POST zum Schreiben.
Christoph Winkler
2
@Michiel $dataist ein assoziatives Array (data [fieldname] = value), das die an die API-Methode gesendeten Daten enthält.
Christoph Winkler
1
Vielen Dank für Ihre Hilfe!
Michiel
2
Beachten Sie, dass die curl_closeFunktion nicht aufgerufen wird. Dies kann zu einem zusätzlichen Speicherverbrauch führen, wenn die CallAPI-Funktion wiederholt aufgerufen wird.
Bart Verkoeijen
1
Die Antwort von @colan unten ist viel besser - es erspart Ihnen den ganzen Aufwand beim Erstellen eigener Fehlerbehandlungs- und Wrapper-Methoden.
Andreas
186

Wenn Sie eine URL haben und Ihr PHP diese unterstützt, können Sie einfach file_get_contents aufrufen:

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

Wenn $ response JSON ist, verwenden Sie json_decode, um es in ein PHP-Array umzuwandeln:

$response = json_decode($response);

Wenn $ response XML ist, verwenden Sie die Klasse simple_xml:

$response = new SimpleXMLElement($response);

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

Andreas Wong
quelle
30
Wenn der REST-Endpunkt einen HTTP-Fehlerstatus zurückgibt (z. B. 401), file_get_contentsschlägt die Funktion mit einer Warnung fehl und gibt null zurück. Wenn der Text eine Fehlermeldung enthält, können Sie diese nicht abrufen.
Bart Verkoeijen
3
Der Hauptnachteil ist, dass für Ihre PHP-Installation fopen-Wrapper aktiviert sein müssen, um auf URLs zugreifen zu können. Wenn fopen-Wrapper nicht aktiviert sind, können Sie file_get_contents nicht für Webdienstanforderungen verwenden.
Oriol
2
fopen-Wrapper gehören zu den Teilen von PHP, die jetzt als Sicherheitslücke angesehen werden. Daher wird es wahrscheinlich von einigen Hosts deaktiviert.
Marcus Downing
153

Verwenden Sie Guzzle . Es handelt sich um einen "PHP-HTTP-Client, der die Arbeit mit HTTP / 1.1 vereinfacht und das Konsumieren von Webdiensten erleichtert". Die Arbeit mit Guzzle ist viel einfacher als die Arbeit mit cURL.

Hier ist ein Beispiel von der Website:

$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
quelle
20
Wer noch cURL verwendet, hat sich diese Option noch nie genauer angesehen.
Joshua David
Scheint gut zu sein. Aber was ist mit dem Abrufen von PNGs? Für Kartenkacheln. Ich kann nur JSON-Daten finden, die auf der von Ihnen verlinkten Webseite aufgeführt sind.
Henrik Erlandsson
20

CURL ist der einfachste Weg. Hier ist ein einfacher Anruf

$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
quelle
1
well @ erm3nda Das OP sagt "Ich weiß also nicht wirklich, wie ich den Service anrufen soll". Holen Sie mir NICHT den besten Weg, eine REST-API zu konsumieren.
Broncha
4
Wow, du verschwendest deine Mühe und Zeit, mir stattdessen eine ironische Antwort zu geben, um deinen Kommentar zu verbessern. Viel Glück auf diese Weise.
m3nda
2
Liebe, wie einfach dieser ist.
Weiter
@ Sadik POST DATA ist nur ein Platzhalter, Sie müssen Ihre Post-Daten dort senden
Broncha
12

Verwenden Sie HTTPFUL

Httpful ist eine einfache, verkettbare und lesbare PHP-Bibliothek, die das Sprechen von HTTP vernünftig machen soll. Der Entwickler kann sich auf die Interaktion mit APIs konzentrieren, anstatt die Seiten von curl set_opt zu durchsuchen, und ist ein idealer PHP-REST-Client.

Httpful beinhaltet ...

  • Unterstützung für lesbare HTTP-Methoden (GET, PUT, POST, DELETE, HEAD und OPTIONEN)
  • Benutzerdefinierte Header
  • Automatische "intelligente" Analyse
  • Automatische Payload-Serialisierung
  • Grundauth
  • Client Side Certificate Auth
  • Fordern Sie "Vorlagen" an

Ex.

Senden Sie eine GET-Anfrage. Erhalten Sie automatisch analysierte JSON-Antworten.

Die Bibliothek bemerkt den JSON-Inhaltstyp in der Antwort und analysiert die Antwort automatisch in ein natives PHP-Objekt.

$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
quelle
Ich versuche, HTTPFUL als Lösung zu verwenden, und ich bin nicht sicher, ob es den JSON wie analysieren kann, es $condition = $response->weather[0]->main;sei denn, ich mache nur die PHP-Seite falsch
Weteamsteve
9

Sie müssen wissen, ob die von Ihnen aufgerufene REST-API GEToder POSToder beide Methoden unterstützt. Der folgende Code funktioniert für mich. Ich rufe meine eigene Webdienst-API auf, sodass ich bereits weiß, was die API benötigt und was sie zurückgibt. Es unterstützt sowohl GETals auch POSTMethoden, so dass die weniger vertraulichen Informationen in die gehen URL (GET)und die Informationen wie Benutzername und Passwort als POSTVariablen übergeben werden. Auch geht alles über die HTTPSVerbindung.

Innerhalb des API-Codes echo $my_json_variablecodiere ich ein Array, das ich in das JSON-Format zurückgeben möchte, und verwende dann einfach den PHP-Befehl , um diese JSON-Zeichenfolge für den Client verfügbar zu machen.

Wie Sie sehen können, gibt meine API JSON-Daten zurück, aber Sie müssen wissen (oder die zurückgegebenen Daten überprüfen, um herauszufinden), in welchem ​​Format die Antwort von der API vorliegt.

So verbinde ich mich von der Clientseite aus mit der 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;
}

Übrigens habe ich auch versucht, die file_get_contents()Methode zu verwenden , wie einige der Benutzer hier vorgeschlagen haben, aber das funktioniert bei mir nicht gut. Ich fand heraus, dass die curlMethode schneller und zuverlässiger ist.

Derek Gogol
quelle
5

Es gibt tatsächlich viele Kunden. Eines davon ist Pest - probieren Sie es aus. Beachten Sie auch, dass es sich bei diesen REST-Aufrufen um einfache http-Anforderungen mit verschiedenen Methoden handelt: GET, POST, PUT und DELETE.

Deadrunk
quelle
4

Sie können zusätzlich zur Methode, wie der Funktionsname andeutet, file_get_contentsbeliebige http- POST/PUT/DELETE/OPTIONS/HEADMethoden ausgeben GET.

Wie poste ich Daten in PHP mit file_get_contents?

Chuan Ma
quelle
1
file_get_content ist wirklich eine schlechte Idee, wenn es um API geht. stackoverflow.com/questions/13004805/… Sie können eine benutzerdefinierte Methode wie file_get_contents_curl festlegen und diese anstelle einer einfachen PHP-Lösung verwenden. stackoverflow.com/questions/8540800/…
Eryk Wróbel
3

Wenn Sie Symfony verwenden, gibt es ein großartiges Rest-Client-Bundle, das sogar alle ~ 100 Ausnahmen enthält und diese auslöst, anstatt einen bedeutungslosen Fehlercode + eine Nachricht zurückzugeben.

Sie sollten es wirklich überprüfen: https://github.com/CircleOfNice/CiRestClientBundle

Ich liebe die Schnittstelle:

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

Funktioniert für alle http-Methoden.

Tobias
quelle
2

Wie @Christoph Winkler erwähnte, ist dies eine Basisklasse, um dies zu erreichen:

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

}

Dann können Sie die Datei jederzeit einschließen und verwenden, z. B.: 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
quelle
0

Wenn Sie offen sind, Tools von Drittanbietern zu verwenden, sehen Sie sich diese an: https://github.com/CircleOfNice/DoctrineRestDriver

Dies ist eine völlig neue Art, mit APIs zu arbeiten.

Zunächst definieren Sie eine Entität, die die Struktur eingehender und ausgehender Daten definiert, und kommentieren sie mit Datenquellen:

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

Jetzt ist es ziemlich einfach, mit der REST-API zu kommunizieren:

$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
quelle
-1

Sie können mit POSTMAN arbeiten, einer Anwendung, die APIs einfach macht. Füllen Sie die Anforderungsfelder aus und es wird Code für Sie in verschiedenen Sprachen generiert. Klicken Sie einfach auf den Code auf der rechten Seite und wählen Sie Ihre bevorzugte Sprache aus.

Xhuljo
quelle