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.
Puedes enviar peticiones con Guzzle usando un objeto GuzzleHttpClientInterface
.
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
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....
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.
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();
}
);
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));
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();
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']);
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']
]);
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.
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'
]
]
]);
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:
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'
]
]
]
]);
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
:
GuzzleHttp\Cookie\CookieJar
almacena las cookies como un array.GuzzleHttp\Cookie\FileCookieJar
persiste las cookies que no son de sesión
utilizando un archivo con formato JSON.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.
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
.
true
para permitir redirecciones normales con un número máximo de 5
redirecciones. Esta es la configuración por defecto.false
para desactivar las redirecciones.$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
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
.
Guzzle expone algunas variables de entorno que pueden utilizarse para personalizar el comportamiento de la biblioteca.
GUZZLE_CURL_SELECT_TIMEOUT
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
NO_PROXY
Guzzle puede utilizar la configuración de PHP ini al configurar los clientes.
openssl.cafile