Guzzle en PSR-7

Guzzle maakt gebruik van PSR-7 als de HTTP berichtinterface. Hierdoor kan Guzzle werken met elke andere bibliotheek die PSR-7 berichtinterfaces gebruikt.

Guzzle is een HTTP client die HTTP verzoeken naar een server stuurt en HTTP antwoorden ontvangt. Zowel verzoeken als antwoorden worden berichten genoemd.

Guzzle vertrouwt op het guzzlehttp/psr7 Composer pakket voor zijn berichtimplementatie van PSR-7.

Je kan een verzoek aanmaken met de GuzzleHttpRequest klasse:

use GuzzleHttp\Psr7\Request;

$request = new Request('GET', 'http://httpbin.org/get');

// You can provide other optional constructor arguments.
$headers = ['X-Foo' => 'Bar'];
$body = 'hello!';
$request = new Request('PUT', 'http://httpbin.org/put', $headers, $body);

Je kan een antwoord maken met de GuzzleHttpResponse klasse:

use GuzzleHttp\Psr7\Response;

// The constructor requires no arguments.
$response = new Response();
echo $response->getStatusCode(); // 200
echo $response->getProtocolVersion(); // 1.1

// You can supply any number of optional arguments.
$status = 200;
$headers = ['X-Foo' => 'Bar'];
$body = 'hello!';
$protocol = '1.1';
$response = new Response($status, $headers, $body, $protocol);

Koppen

Zowel verzoek- als antwoordberichten bevatten HTTP-headers.

Toegang tot kopteksten

Je kan controleren of een request of antwoord een specifieke header heeft met de hasHeader() methode.

use GuzzleHttp\Psr7;

$request = new Psr7\Request('GET', '/', ['X-Foo' => 'bar']);

if ($request->hasHeader('X-Foo')) {
    echo 'It is there';
}

Je kan alle header waarden ophalen als een array van strings met getHeader().

$request->getHeader('X-Foo'); // ['bar']

// Retrieving a missing header returns an empty array.
$request->getHeader('X-Bar'); // []

Je kan de kopteksten van een bericht overlopen met de getHeaders() methode.

foreach ($request->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values) . "\r\n";
}

Complexe kopteksten

Sommige headers bevatten aanvullende informatie over het sleutelwaardepaar. Link headers bevatten bijvoorbeeld een link en verscheidene sleutelwaardeparen:

<http://foo.com>; rel="thing"; type="image/jpeg"

Guzzle biedt een handige functie die kan worden gebruikt om dit soort headers te ontleden:

use GuzzleHttp\Psr7;

$request = new Psr7\Request('GET', '/', [
    'Link' => '<http:/.../front.jpeg>; rel="front"; type="image/jpeg"'
]);

$parsed = Psr7\Header::parse($request->getHeader('Link'));
var_export($parsed);

Zal uitvoeren:

array (
  0 =>
  array (
    0 => '<http:/.../front.jpeg>',
    'rel' => 'front',
    'type' => 'image/jpeg',
  ),
)

Het resultaat bevat een hash van sleutel-waardeparen. Headerwaarden die geen sleutel hebben hebben (d.w.z. de link) worden numeriek geïndexeerd terwijl headerdelen die een sleutel waardepaar vormen, worden toegevoegd als een sleutelwaardepaar.

Body

Zowel verzoek- als antwoordberichten kunnen een body bevatten.

Je kan de body van een bericht ophalen met de getBody() methode:

$response = GuzzleHttp\get('http://httpbin.org/get');
echo $response->getBody();
// JSON string: { ... }

De body die gebruikt wordt in request en response objecten is een PsrttpMessageStreamInterface. Deze stream wordt gebruikt voor zowel het uploaden van gegevens en het downloaden van gegevens. Guzzle zal, standaard, de inhoud van van een bericht opslaan in een stream die gebruik maakt van PHP temp streams. Wanneer de grootte van de body groter is dan 2 MB, zal de stream automatisch overschakelen naar het opslaan van gegevens op schijf in plaats van in het geheugen (om uw toepassing te beschermen tegen geheugenuitputting).

De eenvoudigste manier om een body voor een bericht te maken is met de streamFor methode uit de GuzzleHttpHttpUtils klasse -- Utils::streamFor. Deze methode aanvaardt strings, resources, callables, iterators, andere streamables, en retourneert een instantie van PsrttpMessageStreamInterface.

De body van een verzoek of antwoord kan worden gecast naar een string of u kunt bytes lezen en schrijven van de stream zoals nodig.

use GuzzleHttp\Stream\Stream;
$response = $client->request('GET', 'http://httpbin.org/get');

echo $response->getBody()->read(4);
echo $response->getBody()->read(4);
echo $response->getBody()->read(1024);
var_export($response->eof());

Verzoeken

Verzoeken worden van een client naar een server gestuurd. Verzoeken bevatten de methode die toe te passen op een bron, de identifier van de bron, en de protocol versie die moet worden gebruikt.

Aanvraagmethodes

Bij het maken van een verzoek wordt van u verwacht dat u de HTTP-methode opgeeft die u wilt uit te voeren. Je kunt elke methode opgeven die je wilt, inclusief een aangepaste methode die misschien geen deel uitmaakt van RFC 7231 (zoals "MOVE").

// Create a request using a completely custom HTTP method
$request = new \GuzzleHttp\Psr7\Request('MOVE', 'http://httpbin.org/move');

echo $request->getMethod();
// MOVE

U kunt een verzoek maken en verzenden met methoden op een client die overeenkomen met de HTTP-methode die u wilt gebruiken.

GET
$client->get('http://httpbin.org/get', [/** options **/])
POST
$client->post('http://httpbin.org/post', [/** options **/])
HEAD
$client->head('http://httpbin.org/get', [/** options **/])
PUT
$client->put('http://httpbin.org/put', [/** options **/])
DELETE
$client->delete('http://httpbin.org/delete', [/** options **/])
OPTIES
$client->options('http://httpbin.org/get', [/** options **/])
PATCH
$client->patch('http://httpbin.org/put', [/** options **/])

Bijvoorbeeld:

$response = $client->patch('http://httpbin.org/patch', ['body' => 'content']);

Verzoek URI

De URI van het verzoek wordt voorgesteld door een Psr object. Guzzle biedt een implementatie van deze interface met behulp van de GuzzleHttpMessageUri klasse.

Bij het creëren van een verzoek kunt u de URI opgeven als een string of een instantie van PsrHttpMessageUriInterface.

$response = $client->request('GET', 'http://httpbin.org/get?q=foo');

Schema

Het schema van een verzoek specificeert het protocol dat moet worden gebruikt bij het verzenden van het verzoek. Wanneer je Guzzle gebruikt, kan het schema worden ingesteld op "http" of "https".

$request = new Request('GET', 'http://httpbin.org');
echo $request->getUri()->getScheme(); // http
echo $request->getUri(); // http://httpbin.org

Host

De host is toegankelijk via de URI van het verzoek of door toegang tot de Host-header.

$request = new Request('GET', 'http://httpbin.org');
echo $request->getUri()->getHost(); // httpbin.org
echo $request->getHeader('Host'); // httpbin.org

Port

Er is geen poort nodig wanneer de "http" of "https" schema's worden gebruikt.

$request = new Request('GET', 'http://httpbin.org:8080');
echo $request->getUri()->getPort(); // 8080
echo $request->getUri(); // http://httpbin.org:8080

Path

Het pad van een verzoek is toegankelijk via het URI-object.

$request = new Request('GET', 'http://httpbin.org/get');
echo $request->getUri()->getPath(); // /get

De inhoud van het pad wordt automatisch gefilterd om er zeker van te zijn dat alleen toegestane tekens in het pad aanwezig zijn. Alle tekens die niet zijn toegestaan in het pad worden procentueel gecodeerd volgens RFC 3986 sectie 3.3

Query-string

De querystring van een verzoek kan worden opgevraagd met de getQuery() van het URI object dat eigendom is van het verzoek.

$request = new Request('GET', 'http://httpbin.org/?foo=bar');
echo $request->getUri()->getQuery(); // foo=bar

De inhoud van de querystring wordt automatisch gefilterd om ervoor te zorgen dat alleen toegestane tekens in de querystring aanwezig zijn. Alle tekens die niet toegestaan zijn in de querystring worden procentueel gecodeerd volgens RFC 3986 sectie 3.4

Reacties

Antwoorden zijn de HTTP-berichten die een client van een server ontvangt na het verzenden van een HTTP-verzoekbericht.

Start-Line

De beginregel van een antwoord bevat het protocol en de protocolversie, de statuscode en de redenzin.

$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'http://httpbin.org/get');

echo $response->getStatusCode(); // 200
echo $response->getReasonPhrase(); // OK
echo $response->getProtocolVersion(); // 1.1

Body

Zoals eerder beschreven, kan je de body van een antwoord krijgen met de getBody() methode.

$body = $response->getBody();
echo $body;
// Cast to a string: { ... }
$body->seek(0);
// Rewind the body
$body->read(1024);
// Read bytes of the body

Streams

Guzzle gebruikt PSR-7 stream-objecten om verzoek- en antwoordberichten weer te geven lichamen. Deze stream-objecten stellen u in staat om met verschillende soorten gegevens te werken met behulp van een gemeenschappelijke interface.

HTTP-berichten bestaan uit een startregel, headers, en een body. De body van een HTTP bericht kan zeer klein of extreem groot zijn. Proberen om de body van een bericht als een string kan gemakkelijk meer geheugen gebruiken dan bedoeld omdat de body volledig in het geheugen moet worden opgeslagen. Pogingen om de body van een verzoek of antwoord in het geheugen op te slaan zou het gebruik van die implementatie uitsluiten van te kunnen werken met grote berichtlichamen. De StreamInterface wordt gebruikt om om de implementatiedetails te verbergen van waar een stroom van gegevens wordt gelezen van of naar geschreven wordt.

De PSR-7 Psr stelt verschillende methodes ter beschikking die het mogelijk maken om effectief streams te lezen, er naar te schrijven en ze te doorlopen.

Streams leggen hun mogelijkheden bloot via drie methodes: isReadable(), isWritable(), en isSeekable(). Deze methodes kunnen gebruikt worden door stream om te bepalen of een stream aan hun eisen kan voldoen.

Elke stream-instantie heeft verschillende mogelijkheden: ze kunnen read-only zijn, alleen-schrijven, lezen-schrijven, willekeurige willekeurige toegang toestaan (vooruit of terug naar elke plaats), of alleen sequentiële toegang toestaan (bijvoorbeeld in het geval van een socket of pipe).

Guzzle gebruikt het guzzlehttp/psr7 pakket om stream ondersteuning te bieden. Meer informatie over het gebruik van streams, het creëren van streams, het converteren van streams naar PHP stream resource, en stream decorators kan je vinden in de Guzzle PSR-7 documentatie.

Streams creëren

De beste manier om een stream te maken is met de GuzzleHttp::streamFor methode. Deze methode aanvaardt strings, bronnen geretourneerd door fopen(), een object dat __toString() implementeert, iterators, calllables en instanties van PsrttpMessageStreamInterface.

use GuzzleHttp\Psr7;

$stream = Psr7\Utils::streamFor('string data');
echo $stream;
// string data
echo $stream->read(3);
// str
echo $stream->getContents();
// ing data
var_export($stream->eof());
// true
var_export($stream->tell());
// 11

Je kunt streams maken van iterators. De iterator kan een willekeurig aantal bytes per iteratie opleveren. Overtollige bytes die door de iterator worden teruggegeven en niet door een streamafnemer zijn opgevraagd, worden gebufferd tot een volgende lezing.

use GuzzleHttp\Psr7;

$generator = function ($bytes) {
    for ($i = 0; $i < $bytes; $i++) {
        yield '.';
    }
};

$iter = $generator(1024);
$stream = Psr7\Utils::streamFor($iter);
echo $stream->read(3); // ...

Metadata

Streams geven stream metadata vrij via de getMetadata() methode. Deze methode levert de gegevens die je zou opvragen wanneer je PHP's stream_get_meta_data() functie, en kan optioneel andere aangepaste data blootleggen.

use GuzzleHttp\Psr7;

$resource = Psr7\Utils::tryFopen('/path/to/file', 'r');
$stream = Psr7\Utils::streamFor($resource);
echo $stream->getMetadata('uri');
// /path/to/file
var_export($stream->isReadable());
// true
var_export($stream->isWritable());
// false
var_export($stream->isSeekable());
// true

Stream-decorateurs

Aangepaste functionaliteit toevoegen aan streams is heel eenvoudig met streamdecoratoren. Guzzle biedt verschillende ingebouwde decorators die extra stream functionaliteit bieden.