Guzzle och PSR-7

Guzzle använder PSR-7 som gränssnitt för HTTP-meddelanden. Detta gör det möjligt för Guzzle att arbeta med alla andra bibliotek som använder PSR-7-meddelandegränssnitt.

Guzzle är en HTTP-klient som skickar HTTP-begäranden till en server och tar emot HTTP-svar. Både förfrågningar och svar kallas meddelanden.

Guzzle förlitar sig på paketet guzzlehttp/psr7 Composer för sin meddelandeimplementering av PSR-7.

Du kan skapa en begäran med hjälp av klassen GuzzleHttp\Psr7\Request:

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 skapa ett svar med hjälp av klassen GuzzleHttp\Psr7\Response:

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

Rubriker

Både begäran och svar innehåller HTTP-huvuden.

Tillgång till rubriker

Du kan kontrollera om en begäran eller ett svar har en specifik rubrik med hjälp av metoden hasHeader().

use GuzzleHttp\Psr7;

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

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

Du kan hämta alla headervärden som en array av strängar med hjälp av getHeader().

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

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

Du kan iterera över rubrikerna i ett meddelande med hjälp av metoden getHeaders().

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

Komplexa rubriker

Vissa rubriker innehåller ytterligare information om nyckel- och värdepar. Länkhuvudet innehåller till exempel en länk och flera nyckelvärdespar:

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

Guzzle tillhandahåller en bekvämlighetsfunktion som kan användas för att analysera dessa typer av rubriker:

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

Kommer att ge ut:

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

Resultatet innehåller en hash av nyckel- och värdepar. Rubrikvärden som inte har någon nyckel (dvs. länken) indexeras numeriskt medan rubrikdelar som bildar en nyckel värdepar läggs till som ett nyckelvärdepar.

Body

Både begäran- och svarsmeddelanden kan innehålla en kropp.

Du kan hämta kroppen av ett meddelande med hjälp av metoden getBody():

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

Den kropp som används i begärs- och svarsobjekt är en Psr\Http\Message\StreamInterface. Denna ström används för både uppladdning av data och nedladdning av data. Guzzle kommer som standard att lagra kroppen av ett meddelande i en ström som använder PHP temp streams. När storleken på kroppen överstiger 2 MB kommer strömmen automatiskt att byta till lagring av data på disk. i stället för i minnet (vilket skyddar ditt program från minnesutnyttjande).

Det enklaste sättet att skapa en kropp för ett meddelande är att använda streamFor metoden från GuzzleHttp\Psr7\Utils klassen -- Utils::streamFor. Denna metod accepterar strängar, resurser, callables, iteratorer, andra streamables och returnerar en instans av Psr\Http\Message\StreamInterface.

Kroppen i en begäran eller ett svar kan kastas till en sträng eller så kan du läsa och skriva bytes från 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());

Förfrågningar

Förfrågningar skickas från en klient till en server. Begäranden omfattar metoden för att tillämpas på en resurs, resursens identifierare och protokollet. version som ska användas.

Förfrågningsmetoder

När du skapar en begäran förväntas du ange vilken HTTP-metod du vill använda. utföra. Du kan ange vilken metod som helst, inklusive en anpassad metod. som kanske inte ingår i RFC 7231 (som "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 skapa och skicka en begäran med hjälp av metoder på en klient som motsvarar den HTTP-metod som du vill använda.

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 **/])
OPTIONER
$client->options('http://httpbin.org/get', [/** options **/])
PATCH
$client->patch('http://httpbin.org/put', [/** options **/])

Till exempel:

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

URI för begäran

Förfrågnings-URI:n representeras av ett Psr\Http\Message\UriInterface objekt. Guzzle tillhandahåller en implementering av det här gränssnittet med hjälp av GuzzleHttp\Psr7\Uri.

När du skapar en begäran kan du ange URI:n som en sträng eller en instans av Psr\Http\Message\UriInterface.

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

Scheme

systemet för en begäran anger vilket protokoll som ska användas när begäran skickas. När du använder Guzzle är schema kan ställas in på "http" eller "https".

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

Värd

Värden kan nås med hjälp av den URI som ägs av begäran eller genom att komma åt Host-huvudet.

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

Port

Ingen port behövs när du använder "http"- eller "https"-systemen.

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

Path

Sökvägen för en begäran är tillgänglig via URI-objektet.

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

Innehållet i sökvägen filtreras automatiskt för att säkerställa att endast tillåtna tecken finns i sökvägen. Tecken som inte är tillåtna i sökvägen kommer att procentkodas i enlighet med RFC 3986 avsnitt 3.3

Söksträng

Förfrågningssträngen för en begäran kan nås med hjälp av getQuery() för URI-objektet som ägs av begäran.

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

Innehållet i frågetecken filtreras automatiskt för att säkerställa att endast tillåtna tecken finns i frågeserien. Alla tecken som inte tillåts i frågespänningssträngen kommer att procentkodas enligt följande RFC 3986 avsnitt 3.4

Svar

Svar är de HTTP-meddelanden som en klient får från en server efter att ha skickat ett HTTP-förfrågningsmeddelande.

Startlinje

Startraden i ett svar innehåller protokoll och protokollversion, statuskod och orsaksfras.

$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 tidigare beskrivits kan du hämta kroppen i ett svar med hjälp av metoden getBody().

$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 använder PSR-7-strömobjekt för att representera begäran och svarsmeddelanden. kroppar. Dessa strömobjekt gör det möjligt att arbeta med olika typer av data alla med hjälp av ett gemensamt gränssnitt.

HTTP-meddelanden består av en startrad, rubriker och en kropp. Kroppen i ett HTTP-meddelande meddelande kan vara mycket liten eller extremt stor. Försök att representera kroppen av ett meddelande som en sträng kan lätt ta mer minne i anspråk än vad som var tänkt, eftersom kroppen måste lagras helt och hållet i minnet. Att försöka lagra kroppen av ett begäran eller svar i minnet skulle utesluta användningen av den implementationen från att kunna arbeta med stora meddelandekroppar. StreamInterface används i för att dölja implementationsdetaljerna för var en dataström läses från eller skrivs till.

PSR-7 Psr\Http\Message\StreamInterface har flera metoder som gör att strömmar kan läsas från, skrivas till och genomgås effektivt.

Strömmar visar sina möjligheter med tre metoder: isReadable(), isWritable() och isSeekable(). Dessa metoder kan användas av stream för att avgöra om en ström kan uppfylla deras krav.

Varje ströminstans har olika möjligheter: de kan vara skrivskyddade, skrivskyddade, skrivskyddade, tillåta godtycklig slumpmässig åtkomst (sökning framåt eller framåt). bakåt till vilken plats som helst), eller endast tillåta sekventiell åtkomst (t.ex. i fallet med en socket eller pipe).

Guzzle använder paketet guzzlehttp/psr7 för att ge stöd för strömmar. Mer information om att använda strömmar, skapa strömmar, konvertera strömmar till PHP strömresurs, och strömdekoratorer finns i Guzzle PSR-7 documentation.

Skapa strömmar

Det bästa sättet att skapa en ström är att använda GuzzleHttp\Psr7\Utils::streamFor metod. Denna metod accepterar strängar, resurser som returneras från fopen(), ett objekt som implementerar __toString(), iteratorer, callables och instanser. av 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 skapa strömmar från iteratorer. Iteratorn kan ge ett valfritt antal bytes per iteration. Alla överflödiga bytes som returneras av iteratorn och som inte var begärdes inte av en stream-konsument kommer att buffras till en senare 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 exponerar metadata om strömmen genom metoden getMetadata(). Denna metod tillhandahåller de data som du skulle hämta när du anropar PHP:s stream_get_meta_data() funktion, och kan eventuellt visa andra anpassade 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 är mycket enkelt att lägga till anpassad funktionalitet till strömmar med strömdekoratorer. Guzzle tillhandahåller flera inbyggda dekoratorer som ger ytterligare stream funktionalitet.