Guzzle og PSR-7

Guzzle anvender PSR-7 som HTTP-meddelelsesgrænseflade. Dette gør det muligt for Guzzle at arbejde sammen med ethvert andet bibliotek, der anvender PSR-7-meddelelsesgrænseflader.

Guzzle er en HTTP-klient, der sender HTTP-forespørgsler til en server og modtager HTTP-svar. Både anmodninger og svar betegnes som meddelelser.

Guzzle er afhængig af guzzlehttp/psr7 Composer-pakken for sin implementering af PSR-7 til meddelelser.

Du kan oprette en anmodning ved hjælp af GuzzleHttp\Psr7\Request klassen:

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

Du kan oprette et svar ved hjælp af GuzzleHttp\Psr7\Response klassen:

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

Overskrifter

Både anmodnings- og svarmeddelelser indeholder HTTP-headere.

Adgang til overskrifter

Du kan kontrollere, om en anmodning eller et svar har en bestemt header ved hjælp af hasHeader() metoden.

use GuzzleHttp\Psr7;

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

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

Du kan hente alle header-værdierne som et array af strenge ved hjælp af getHeader().

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

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

Du kan iterere over overskrifterne i en meddelelse ved hjælp af getHeaders() metoden.

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

Komplekse overskrifter

Nogle overskrifter indeholder yderligere oplysninger om nøgle-værdipar. Link-headere indeholder f.eks. et link og flere nøgleværdipar:

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

Guzzle indeholder en bekvemmelighedsfunktion, der kan bruges til at analysere disse typer af overskrifter:

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

Vil output:

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

Resultatet indeholder en hash af nøgle-værdipar. Header-værdier, der ikke har nogen nøgle (dvs. linket) indekseres numerisk, mens headers dele, der udgør en nøgle værdipar tilføjes som et nøgleværdipar.

Body

Både anmodnings- og svarmeddelelser kan indeholde en krop.

Du kan hente kroppen af en meddelelse ved hjælp af getBody() metoden:

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

Den krop, der anvendes i anmodnings- og svarobjekter, er en Psr\Http\Message\StreamInterface. Denne stream bruges til både uploading af data og downloading af data. Guzzle vil som standard gemme kroppen af en meddelelse i en stream, der bruger PHP temp streams. Når størrelsen af kroppen overstiger 2 MB, vil strømmen automatisk skifte til lagring af data på disk i stedet for i hukommelsen (hvilket beskytter din applikation mod hukommelsesudtømning).

Den nemmeste måde at oprette en krop til en meddelelse på er ved hjælp af streamFor metode fra GuzzleHttp\Psr7\Utils klassen -- Utils::streamFor. Denne metode accepterer strings, ressourcer, callables, iteratorer, andre streamables, og returnerer en instans af Psr\Http\Message\StreamInterface.

Kroppen af en forespørgsel eller et svar kan kastes til en streng, eller du kan læse og skrive bytes fra strømmen efter behov.

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());

Anmodninger

Anmodninger sendes fra en klient til en server. Anmodninger omfatter metoden til at der skal anvendes på en ressource, ressourcens identifikator og protokollen version, der skal anvendes.

Anmodningsmetoder

Når du opretter en anmodning, forventes det, at du angiver den HTTP-metode, du ønsker du ønsker at udføre. Du kan angive enhver metode, du ønsker, herunder en brugerdefineret metode der måske ikke er en del af RFC 7231 (som f.eks. "MOVE").

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

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

Du kan oprette og sende en anmodning ved hjælp af metoder på en klient, der svarer til den HTTP-metode, du ønsker at bruge.

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

For eksempel:

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

Anmodning om URI

Anmodnings-URI'en repræsenteres af et Psr\Http\Message\UriInterface objekt. Guzzle tilbyder en implementering af denne grænseflade ved hjælp af GuzzleHttp\Psr7\Uri klassen.

Når du opretter en anmodning, kan du angive URI'en som en streng eller en instans af Psr\Http\Message\UriInterface.

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

Ordning

skema for en anmodning angiver den protokol, der skal anvendes ved afsendelse af anmodningen. Når man bruger Guzzle, skal skema kan indstilles til "http" eller "https".

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

Host

Værten er tilgængelig ved hjælp af den URI, der tilhører anmodningen, eller ved at få adgang til Host-headeren.

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

Port

Det er ikke nødvendigt med en port, når du bruger "http"- eller "https"-ordningerne.

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

Sti

Stien for en anmodning er tilgængelig via URI-objektet.

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

Indholdet af stien vil automatisk blive filtreret for at sikre, at kun tilladte tegn er til stede i stien. Alle tegn, der ikke er tilladt i stien vil blive procent-kodet i henhold til RFC 3986 afsnit 3.3

Forespørgselsstreng

Forespørgselsstrengen for en anmodning kan tilgås ved hjælp af getQuery() for URI-objektet, der ejes af anmodningen.

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

Indholdet af forespørgselsstrengen vil automatisk blive filtreret for at sikre, at kun tilladte tegn er til stede i forespørgselsstrengen. Alle tegn, der ikke er tilladt i forespørgselsstrengen, vil blive procentkodet i henhold til RFC 3986 afsnit 3.4

Svar

Svar er de HTTP-meddelelser, som en klient modtager fra en server efter at have sendt en HTTP-anmodningsmeddelelse.

Start-linje

Startlinjen i et svar indeholder protokol og protokolversion, statuskode og årsagssætning.

$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

Som beskrevet tidligere kan du få fat i kroppen af et svar ved hjælp af getBody() metoden.

$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 bruger PSR-7 stream-objekter til at repræsentere anmodnings- og svarmeddelelser organer. Disse stream-objekter giver dig mulighed for at arbejde med forskellige typer af data, som alle ved hjælp af en fælles grænseflade.

HTTP-meddelelser består af en startlinje, overskrifter og en krop. Kroppen af en HTTP besked kan være meget lille eller ekstremt stor. Forsøg på at repræsentere kroppen af en meddelelse som en streng kan nemt opbruge mere hukommelse end tilsigtet, fordi kroppen skal gemmes fuldstændigt i hukommelsen. Forsøg på at gemme kroppen af en anmodning eller svar i hukommelsen ville udelukke brugen af denne implementering fra være i stand til at arbejde med store meddelelseskorpusser. StreamInterface anvendes i for at skjule implementeringsdetaljerne vedrørende hvor en datastrøm læses fra eller skrives til.

PSR-7 Psr\Http\Message\\StreamInterface indeholder flere metoder, der gør det muligt at læse fra, skrive til og gennemløbe streams effektivt.

Streams afslører deres funktioner ved hjælp af tre metoder: isReadable(), isWritable(), og isSeekable(). Disse metoder kan bruges af stream samarbejdspartnere til at afgøre, om en stream er i stand til at opfylde deres krav.

Hver stream-instans har forskellige muligheder: de kan være skrivebeskyttede, skrivebeskyttet, skrive- og skrivebeskyttet, tillade vilkårlig tilfældig adgang (søge fremad eller baglæns til et vilkårligt sted), eller kun tillade sekventiel adgang (f.eks. i tilfælde af en socket eller pipe).

Guzzle bruger pakken guzzlehttp/psr7 til at levere understøttelse af stream. Mere oplysninger om brug af streams, oprettelse af streams, konvertering af streams til PHP stream-ressource og stream-dekoratorer kan findes i Guzzle PSR-7 dokumentation.

Oprettelse af strømme

Den bedste måde at oprette en stream på er at bruge GuzzleHttp\Psr7\Utils::streamFor metode. Denne metode accepterer strenge, ressourcer, der returneres fra fopen(), et objekt, der implementerer __toString(), iteratorer, callables og instanser af Psr\Http\Message\StreamInterface.

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

Du kan oprette strømme fra iteratorer. Iteratoren kan give et vilkårligt antal bytes pr. iteration. Alle overskydende bytes, der returneres af iteratoren, som ikke var anmodet om af en streamforbruger, vil blive gemt i en buffer indtil en efterfølgende læsning.

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 eksponerer stream-metadata gennem getMetadata() metoden. Denne metode giver de data, du ville hente, når du kalder PHP's stream_get_meta_data()-funktion, og kan eventuelt udsætte andre brugerdefinerede data.

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 Decorators

Det er meget enkelt at tilføje brugerdefinerede funktioner til streams med stream-dekoratorer. Guzzle indeholder flere indbyggede dekoratorer, der giver yderligere stream funktionalitet.