Inicio rápido

Esta página proporciona una rápida introducción a Guzzle y ejemplos introductorios. Si aún no has instalado Guzzle, dirígete a la Instalación página.

Hacer una solicitud

Puedes enviar peticiones con Guzzle usando un objeto GuzzleHttpClientInterface.

Crear un cliente

use GuzzleHttp\Client;

$client = new Client([
    // Base URI is used with relative requests
    'base_uri' => 'http://httpbin.org',
    // You can set any number of default request options.
    'timeout'  => 2.0,
]);

Los clientes son inmutables en Guzzle, lo que significa que no puedes cambiar los valores predeterminados utilizados por un cliente después de su creación.

El constructor del cliente acepta una matriz asociativa de opciones:

base_uri

(string|UriInterface) URI base del cliente que se fusiona en los URIs. Puede ser una cadena o una instancia de UriInterface. Cuando se proporciona un URI relativo se proporciona a un cliente, éste combinará el URI base con el URI relativo utilizando las reglas descritas en RFC 3986, sección 5.2.

// Crear un cliente con una URI base
$client = new GuzzleHttp\Client(['base_uri' => 'https://foo.com/api/']);
// Enviar una solicitud a https://foo.com/api/test
$response = $client->request('GET', 'test');
// Enviar una solicitud a https://foo.com/root
$response = $client->request('GET', '/root');

¿No tienes ganas de leer el RFC 3986? Aquí tienes algunos ejemplos rápidos sobre cómo se resuelve una base_uri con otra URI.

base_uri URI Resultado
http://foo.com /barra http://foo.com/bar
http://foo.com/foo /barra http://foo.com/bar
http://foo.com/foo bar http://foo.com/bar
http://foo.com/foo/ bar http://foo.com/foo/bar
http://foo.com http://baz.com http://baz.com
http://foo.com/?bar bar http://foo.com/bar
handler
(callable) Función que transfiere las peticiones HTTP a través del cable. La función función se llama con un Psr7\Http\Message\RequestInterface y un array de opciones de transferencia, y debe devolver un GuzzleHttp\Promise\PromiseInterface que se cumple con un Psr7\Http\Message\ResponseInterface en caso de éxito.
...
(mixto) Todas las demás opciones pasadas al constructor se utilizan como opciones de solicitud por defecto con cada solicitud creada por el cliente.

Envío de solicitudes

Los métodos mágicos en el cliente facilitan el envío de peticiones sincrónicas:

$response = $client->get('http://httpbin.org/get');
$response = $client->delete('http://httpbin.org/delete');
$response = $client->head('http://httpbin.org/get');
$response = $client->options('http://httpbin.org/get');
$response = $client->patch('http://httpbin.org/patch');
$response = $client->post('http://httpbin.org/post');
$response = $client->put('http://httpbin.org/put');

Puede crear una solicitud y luego enviarla con el cliente cuando esté listo:

use GuzzleHttp\Psr7\Request;

$request = new Request('PUT', 'http://httpbin.org/put');
$response = $client->send($request, ['timeout' => 2]);

Los objetos cliente proporcionan una gran flexibilidad en la forma de transferir incluyendo opciones de solicitud por defecto, middleware de pila de manejadores por defecto que son utilizados por cada solicitud, y un URI base que permite enviar solicitudes con URIs relativas.

Puedes encontrar más información sobre el middleware del cliente en la página Handlers and Middleware de la documentación.

Solicitudes asíncronas

Se pueden enviar peticiones asíncronas utilizando los métodos mágicos proporcionados por un cliente:

$promise = $client->getAsync('http://httpbin.org/get');
$promise = $client->deleteAsync('http://httpbin.org/delete');
$promise = $client->headAsync('http://httpbin.org/get');
$promise = $client->optionsAsync('http://httpbin.org/get');
$promise = $client->patchAsync('http://httpbin.org/patch');
$promise = $client->postAsync('http://httpbin.org/post');
$promise = $client->putAsync('http://httpbin.org/put');

También puedes utilizar los métodos sendAsync() y requestAsync() de un cliente:

use GuzzleHttp\Psr7\Request;

// Create a PSR-7 request object to send
$headers = ['X-Foo' => 'Bar'];
$body = 'Hello!';
$request = new Request('HEAD', 'http://httpbin.org/head', $headers, $body);
$promise = $client->sendAsync($request);

// Or, if you don't need to pass in a request instance:
$promise = $client->requestAsync('GET', 'http://httpbin.org/get');

La promesa devuelta por estos métodos implementa la Promises/A+ spec, proporcionada por la Guzzle promises library. Esto significa que puedes encadenar then() llamadas a partir de la promesa. Estas llamadas then se se cumplen con un éxito Psr\Http\Message\ResponseInterface o rechazado con una excepción.

use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;

$promise = $client->requestAsync('GET', 'http://httpbin.org/get');
$promise->then(
    function (ResponseInterface $res) {
        echo $res->getStatusCode() . "\n";
    },
    function (RequestException $e) {
        echo $e->getMessage() . "\n";
        echo $e->getRequest()->getMethod();
    }
);

Solicitudes concurrentes

Puedes enviar múltiples peticiones de forma concurrente utilizando promesas y peticiones asíncronas.

use GuzzleHttp\Client;
use GuzzleHttp\Promise;

$client = new Client(['base_uri' => 'http://httpbin.org/']);

// Initiate each request but do not block
$promises = [
    'image' => $client->getAsync('/image'),
    'png'   => $client->getAsync('/image/png'),
    'jpeg'  => $client->getAsync('/image/jpeg'),
    'webp'  => $client->getAsync('/image/webp')
];

// Wait for the requests to complete; throws a ConnectException
// if any of the requests fail
$responses = Promise\Utils::unwrap($promises);

// You can access each response using the key of the promise
echo $responses['image']->getHeader('Content-Length')[0];
echo $responses['png']->getHeader('Content-Length')[0];

// Wait for the requests to complete, even if some of them fail
$responses = Promise\Utils::settle($promises)->wait();

// Values returned above are wrapped in an array with 2 keys: "state" (either fulfilled or rejected) and "value" (contains the response)
echo $responses['image']['state']; // returns "fulfilled"
echo $responses['image']['value']->getHeader('Content-Length')[0];
echo $responses['png']['value']->getHeader('Content-Length')[0];

Puedes utilizar el objeto GuzzleHttp\Pool cuando tengas una cantidad indeterminada de peticiones que quieras enviar.

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;

$client = new Client();

$requests = function ($total) {
    $uri = 'http://127.0.0.1:8126/guzzle-server/perf';
    for ($i = 0; $i < $total; $i++) {
        yield new Request('GET', $uri);
    }
};

$pool = new Pool($client, $requests(100), [
    'concurrency' => 5,
    'fulfilled' => function (Response $response, $index) {
        // this is delivered each successful response
    },
    'rejected' => function (RequestException $reason, $index) {
        // this is delivered each failed request
    },
]);

// Initiate the transfers and create a promise
$promise = $pool->promise();

// Force the pool of requests to complete.
$promise->wait();

O utilizando un cierre que devolverá una promesa una vez que el pool llame al cierre.

$client = new Client();

$requests = function ($total) use ($client) {
    $uri = 'http://127.0.0.1:8126/guzzle-server/perf';
    for ($i = 0; $i < $total; $i++) {
        yield function() use ($client, $uri) {
            return $client->getAsync($uri);
        };
    }
};

$pool = new Pool($client, $requests(100));

Uso de respuestas

En los ejemplos anteriores, recuperamos una variable $response o se nos entregado una respuesta de una promesa. El objeto respuesta implementa un PSR-7 respuesta, Psr\Http\Message\ResponseInterface, y contiene mucha información útil.

Puede obtener el código de estado y la frase de la razón de la respuesta:

$code = $response->getStatusCode(); // 200
$reason = $response->getReasonPhrase(); // OK

Puede recuperar las cabeceras de la respuesta:

// Check if a header exists.
if ($response->hasHeader('Content-Length')) {
    echo "It exists";
}

// Get a header from the response.
echo $response->getHeader('Content-Length')[0];

// Get all of the response headers.
foreach ($response->getHeaders() as $name => $values) {
    echo $name . ': ' . implode(', ', $values) . "\r\n";
}

El cuerpo de una respuesta puede recuperarse utilizando el método getBody. El cuerpo puede ser usado como una cadena, convertido en una cadena, o usado como un objeto tipo stream.

$body = $response->getBody();
// Implicitly cast the body to a string and echo it
echo $body;
// Explicitly cast the body to a string
$stringBody = (string) $body;
// Read 10 bytes from the body
$tenBytes = $body->read(10);
// Read the remaining contents of the body as a string
$remainingBytes = $body->getContents();

Parámetros de la cadena de consulta

Puede proporcionar parámetros de cadena de consulta con una solicitud de varias maneras.

Puede establecer parámetros de cadena de consulta en el URI de la solicitud:

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

Puede especificar los parámetros de la cadena de consulta utilizando la opción de solicitud query como una matriz.

$client->request('GET', 'http://httpbin.org', [
    'query' => ['foo' => 'bar']
]);

Al proporcionar la opción como un array se utilizará la función http_build_query de PHP para formatear la cadena de consulta.

Y por último, puede proporcionar la opción de solicitud query como una cadena.

$client->request('GET', 'http://httpbin.org', ['query' => 'foo=bar']);

Carga de datos

Guzzle ofrece varios métodos para cargar datos.

Puedes enviar peticiones que contengan un flujo de datos pasando una cadena un recurso devuelto por fopen, o una instancia de una Psr\Http\Message\StreamInterface a la opción de solicitud body.

use GuzzleHttp\Psr7;

// Provide the body as a string.
$r = $client->request('POST', 'http://httpbin.org/post', [
    'body' => 'raw data'
]);

// Provide an fopen resource.
$body = Psr7\Utils::tryFopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

// Use the Utils::streamFor method to create a PSR-7 stream.
$body = Psr7\Utils::streamFor('hello!');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

Una forma sencilla de subir datos JSON y establecer la cabecera adecuada es utilizando la opción de solicitud json:

$r = $client->request('PUT', 'http://httpbin.org/put', [
    'json' => ['foo' => 'bar']
]);

POST/Solicitudes de formularios

Además de especificar los datos brutos de una solicitud utilizando la opción de solicitud body, Guzzle proporciona abstracciones útiles sobre el envío de datos POST.

Envío de campos de formulario

El envío de solicitudes application/x-www-form-urlencoded POST requiere que se especifiquen los campos POST como una matriz en las opciones de solicitud form_params.

$response = $client->request('POST', 'http://httpbin.org/post', [
    'form_params' => [
        'field_name' => 'abc',
        'other_field' => '123',
        'nested_field' => [
            'nested' => 'hello'
        ]
    ]
]);

Envío de archivos de formulario

Puede enviar archivos junto con un formulario (solicitudes POST multipart/form-data), utilizando la opción de solicitud multipart. multipart acepta un array de matrices asociativas, donde cada matriz asociativa contiene las siguientes claves:

  • name: (obligatorio, cadena) clave que asigna el nombre del campo del formulario.
  • contenido: (obligatorio, mixto) Proporcionar una cadena para enviar el contenido del archivo como una cadena, proporcione un recurso fopen para transmitir el contenido desde un PHP, o proporcionar un Psr\Http\Message\StreamInterface para transmitir el contenido de un flujo PSR-7.
use GuzzleHttp\Psr7;

$response = $client->request('POST', 'http://httpbin.org/post', [
    'multipart' => [
        [
            'name'     => 'field_name',
            'contents' => 'abc'
        ],
        [
            'name'     => 'file_name',
            'contents' => Psr7\Utils::tryFopen('/path/to/file', 'r')
        ],
        [
            'name'     => 'other_file',
            'contents' => 'hello',
            'filename' => 'filename.txt',
            'headers'  => [
                'X-Foo' => 'this is an extra header to include'
            ]
        ]
    ]
]);

Cookies

Guzzle puede mantener una sesión de cookies por ti si se le indica usando la opción de petición cookies opción de solicitud. Al enviar una solicitud, la opción cookies debe establecerse en una instancia de GuzzleHttp\Cookie\CookieJarInterface.

// Use a specific cookie jar
$jar = new \GuzzleHttp\Cookie\CookieJar;
$r = $client->request('GET', 'http://httpbin.org/cookies', [
    'cookies' => $jar
]);

Puede establecer cookies a true en un constructor de cliente si desea utilizar un bote de cookies compartido para todas las peticiones.

// Use a shared client cookie jar
$client = new \GuzzleHttp\Client(['cookies' => true]);
$r = $client->request('GET', 'http://httpbin.org/cookies');

Existen diferentes implementaciones para la GuzzleHttp\Cookie\CookieJarInterface :

  • La clase GuzzleHttp\Cookie\CookieJar almacena las cookies como un array.
  • La clase GuzzleHttp\Cookie\FileCookieJar persiste las cookies que no son de sesión utilizando un archivo con formato JSON.
  • La clase GuzzleHttp\Cookie\SessionCookieJar persiste las cookies en la sesión del cliente.

Puedes colocar manualmente las cookies en un tarro de cookies con el constructor con nombre fromArray(array $cookies, $domain).

$jar = \GuzzleHttp\Cookie\CookieJar::fromArray(
    [
        'some_cookie' => 'foo',
        'other_cookie' => 'barbaz1234'
    ],
    'example.org'
);

Puedes obtener una cookie por su nombre con el método getCookieByName($name) que devuelve una instancia de GuzzleHttp\CookieSetCookie.

$cookie = $jar->getCookieByName('some_cookie');

$cookie->getValue(); // 'foo'
$cookie->getDomain(); // 'example.org'
$cookie->getExpires(); // expiration date as a Unix timestamp

Las cookies también pueden ser recuperadas en un array gracias al método toArray(). La interfaz GuzzleHttp\Cookie\CookieJarInterface extiende Traversable para que pueda ser iterada en un bucle foreach.

Redirecciones

Guzzle seguirá automáticamente las redirecciones a menos que le digas que no lo haga. Puedes personalizar el comportamiento de las redirecciones utilizando la opción de petición allow_redirects.

  • Establecer a true para permitir redirecciones normales con un número máximo de 5 redirecciones. Esta es la configuración por defecto.
  • Establezca false para desactivar las redirecciones.
  • Pasar un array asociativo que contenga la clave 'max' para especificar el número máximo de número de redirecciones y, opcionalmente, una clave "strict" para especificar para especificar si se utilizan o no redireccionamientos estrictos conforme a la RFC (es decir, redirigir las peticiones POST POST con peticiones POST en lugar de hacer lo que la mayoría de los navegadores hacen, que es redirigir las peticiones POST con peticiones GET).
$response = $client->request('GET', 'http://github.com');
echo $response->getStatusCode();
// 200

El siguiente ejemplo muestra que los redireccionamientos pueden ser desactivados.

$response = $client->request('GET', 'http://github.com', [
    'allow_redirects' => false
]);
echo $response->getStatusCode();
// 301

Excepciones

Vista de árbol

La siguiente vista de árbol describe cómo las excepciones de Guzzle dependen unas de otras.

. \RuntimeException
└── TransferException (implements GuzzleException)
    ├── ConnectException (implements NetworkExceptionInterface)
    └── RequestException
        ├── BadResponseException
        │   ├── ServerException
        │   └── ClientException
        └── TooManyRedirectsException

Guzzle lanza excepciones para los errores que se producen durante una transferencia.

  • Se lanza una GuzzleHttpException\ConnectException excepción en caso de caso de un error de red. Esta excepción se extiende desde GuzzleHttp\Exception\TransferException.

  • Se lanza una GuzzleHttp\Exception\ClientException para errores de nivel 400 si la opción de solicitud http_errors está establecida en true. Este excepción se extiende desde GuzzleHttpException\BadResponseException y GuzzleHttp\Exception\BadResponseException extiende de GuzzleHttp\Exception\RequestException.

    use GuzzleHttp\Psr7;
    use GuzzleHttp\Exception\ClientException;
    
    try {
        $client->request('GET', 'https://github.com/_abc_123_404');
    } catch (ClientException $e) {
        echo Psr7\Message::toString($e->getRequest());
        echo Psr7\Message::toString($e->getResponse());
    }
    
  • Se lanza una GuzzleHttp\Exception\ServerException para errores de nivel 500 si la opción de solicitud http_errors está establecida en true. Este excepción se extiende desde GuzzleHttpException\BadResponseException.

  • Se lanza una GuzzleHttp\Exception\TooManyRedirectsException cuando se siguen demasiadas demasiadas redirecciones. Esta excepción se extiende desde GuzzleHttpException\RequestException.

Todas las excepciones anteriores se extienden desde GuzzleHttp\Exception\TransferException.

Variables de entorno

Guzzle expone algunas variables de entorno que pueden utilizarse para personalizar el comportamiento de la biblioteca.

GUZZLE_CURL_SELECT_TIMEOUT
Controla la duración en segundos que un manejador curl_multi_* utilizará cuando seleccionar en los manejadores curl usando curl_multi_select(). Algunos sistemas tienen problemas con la implementación de PHP de curl_multi_select() donde llamar a esta función siempre resulta en la espera de la duración máxima de el tiempo de espera.
HTTP_PROXY

Define el proxy a utilizar cuando se envían peticiones utilizando el protocolo "http"

Nota: debido a que la variable HTTP_PROXY puede contener información arbitraria del usuario en algunos entornos (CGI), la variable sólo se utiliza en el CLI SAPI. Ver https://httpoxy.org para más información.

HTTPS_PROXY
Define el proxy que se utilizará cuando se envíen solicitudes mediante el protocolo "https".
NO_PROXY
Define las URL para las que no se debe utilizar un proxy. Ver proxy para su uso.

Ajustes ini relevantes

Guzzle puede utilizar la configuración de PHP ini al configurar los clientes.

openssl.cafile
Especifica la ruta de acceso en disco a un archivo CA en formato PEM que se utilizará al enviar solicitudes a través de "https". Ver: https://wiki.php.net/rfc/tls-peer-verification#phpini_defaults