In zwei kürzlich geschriebenen Artikeln bin ich bereits auf die REST-API von WooCommerce eingegangen, sowie auf einen PHP-Bibliothek von Automattic, die die Nutzung der API mit PHP vereinfacht. Hier stelle ich einen Weg vor, wie mehrere Anfragen gleichzeitig an den Shop gemacht werden können.
Das Problem bei der »normalen« Nutzung der API via PHP
Wenn die API so genutzt wird wie in meinen beiden Beiträgen geschrieben, dann läuft das PHP-Programm erst weiter, wenn der HTTP-Request fertig ist. Bei einigen wenigen Requests oder bei vielen einzelnen Requests, die alle direkt voneinander abhängen, ist das das gewünschte Verhalten.
Wenn allerdings API-Requests abgefeuert werden, die gebündelt werden könnten, weil beispielsweise mehrere Produkte angelegt werden sollen, dann wäre es schön diese parallel starten zu können, um die Laufzeit des Skripts verkürzen zu können. Das ist – soweit ich weiß – mit der offiziellen PHP-Bibliothek für die REST-API nicht möglich.
Die Lösung: Die Requests-Bibliothek
Über den Beitrag »A Guide to Async HTTP Requests for WordPress« von Josh Pollock bin ich auf die Requests-Bibliothek von Ryan McCue aufmerksam geworden, die seit einiger Zeit fester Bestandteil von WordPress ist. Über deren request_multiple()
-Methode können mehrere HTTP-Requests parallel gemacht werden – perfekt also für das geplante Vorhaben.
Um zwei GET-Anfragen gleichzeitig zu starten, wird beispielsweise der folgende Code benötigt:
$requests_array = [
[
'url' => 'https://example.com/api-endpoint-1',
'type' => 'GET',
],
[
'url' => 'https://example.com/api-endpoint-2',
'type' => 'GET',
],
];
$responses = Requests::request_multiple( $requests_array );
Code-Sprache: PHP (php)
In $responses
sind dann die Ergebnisse der beiden Anfragen gespeichert.
Nutzung der Requests-Bibliothek für die WooCommerce-API
Für die nachfolgenden Schritte sei angemerkt: ich habe es nicht lokal zum Laufen gebracht, da request_multiple()
momentan nicht mit selbst erstellten SSL-Zertifikaten funktioniert (normalerweise lässt sich die Prüfung unterbinden, ob es sich um ein vertrauenswürdiges Zertifikat handelt) und ich beim Versuch der Authentifizierung via OAuth1 gescheitert bin. Das einfachste ist, es auf einem richtigen Server mit gültigem SSL-Zertifikat auszuprobieren.
Um mit der WooCommerce-API zu kommunizieren, brauchen wir eine URL nach dem folgenden Format (consumer_key
und consumer_secret
könnten glaube ich auch über HTTP-Header übertragen werden, das habe ich mir aber nicht angeschaut):
Code-Sprache: Bash (bash)https://example.com/wp-json/wc/v2/products/categories?consumer_key=ck_000&consumer_secret=cs_000
Der erste Teil bis zum Endpoint products/categories
ist fest, und die beiden Parameter consumer_key
und consumer_secret
verändern sich bei der Kommunikation mit ein und demselben Shop auch nicht. Wir bauen uns der Übersichtlichkeit halber eine kleine Hilfsfunktion, an die wir den Endpunkt und gegebenenfalls weitere URL-Parameter übergeben und eine URL nach dem obigen Format zurückbekommen:
/**
* Returns URL for accessing the provided WooCommerce REST API endpoint.
*
* @param string $endpoint API endpoint.
* @param array $parameters Optional parameters.
*
* @return string
*/
function build_api_url( $endpoint, $parameters = [] ) {
// Add trailing slash to URL.
$url = trailingslashit( 'https://example.com/wp-json/wc/v2/' ) . $endpoint;
$api_url = add_query_arg( \array_merge( $parameters, [
'consumer_key' => 'ck_000',
'consumer_secret' => 'cs_000',
] ), $url );
return $api_url;
}
Code-Sprache: PHP (php)
Und jetzt könnten wir uns beispielsweise die Produkt-Kategorien und -Attribute wie folgt holen:
// Make requests to get existing categories and attributes.
$requests = [
[
'url' => build_api_url( 'products/categories' ),
'type' => 'GET',
],
[
'url' => build_api_url( 'products/attributes' ),
'type' => 'GET',
]
];
$responses = Requests::request_multiple( $requests );
Code-Sprache: PHP (php)
Um zum Beispiel mehrere Produkte anzulegen, könnten Daten von anzulegenden Produkten in einer Schleife durchlaufen werden und dabei ein temporäres Array mit den Request-Daten gefüllt werden, das dann in etwa so aussieht:
$tmp_requests_array[] = [
'url' => build_api_url( "products" ),
'type' => 'POST',
'data' => $prod_data,
];
Code-Sprache: PHP (php)
$prod_data
ist dabei ein Array der Produktdaten, wie es aus meinem Artikel »WooCommerce-Produkt mit PHP über die REST-API hinzufügen«. Nachdem die Produkte durchlaufen wurden und das Array mit den Requests fertig ist, wird es an request_multiple()
übergeben. Hier sollte eventuell nur darauf geachtet werden, nicht zu viele Anfragen gleichzeitig an den Server zu schicken.
Ein Punkt, der bei requests_multiple()
aktuell neben der Deaktivierung der SSL-Prüfung ebenfalls noch nicht funktioniert ist die Übergabe von User und Passwort, um einen via .htaccess geschützten Shop anzusprechen.