kriswallsmith/buzz
Lightweight PHP HTTP client (PSR-7/PSR-17) for scripted requests. Includes FileGetContents, Curl and MultiCurl clients with batch requests and HTTP/2 server push support. Simple Browser API or low-level request sending.
Installation:
composer require kriswallsmith/buzz nyholm/psr7
nyholm/psr7).First Request:
use Buzz\Browser;
use Buzz\Client\Curl;
use Nyholm\Psr7\Factory\Psr17Factory;
$factory = new Psr17Factory();
$client = new Curl($factory);
$browser = new Browser($client, $factory);
$response = $browser->get('https://example.com');
echo $response->getStatusCode(); // 200
Key Classes:
Browser: High-level wrapper for HTTP requests (supports middleware).Curl, FileGetContents, MultiCurl: Low-level clients (choose based on needs).Psr17Factory: Required for PSR-7 request/response creation.$browser->addMiddleware(new \Buzz\Middleware\LoggerMiddleware());
$browser->addMiddleware(new \Buzz\Middleware\BasicAuthMiddleware('user', 'pass'));
$response = $browser->submitForm(
'https://example.com/login',
['email' => 'user@example.com', 'password' => 'secret']
);
$browser->setHeader('X-Custom-Header', 'value');
$client = new Curl($factory, ['timeout' => 10, 'verify_peer' => false]);
$response = $client->sendRequest($request, ['expose_curl_info' => true]);
$multiClient = new MultiCurl($factory);
$multiClient->sendAsyncRequest($request1);
$multiClient->sendAsyncRequest($request2);
$responses = $multiClient->proceed(); // Array of responses
$client = new MultiCurl($factory);
$response = $client->sendRequest($request, ['http_version' => '2.0']);
// app/Providers/BuzzServiceProvider.php
public function register()
{
$this->app->singleton('buzz.browser', function () {
$factory = new Psr17Factory();
$client = new Curl($factory);
return new Browser($client, $factory);
});
}
// app/Facades/Buzz.php
public static function get($url) {
return app('buzz.browser')->get($url);
}
$browser->addMiddleware(new class implements \Buzz\Middleware {
public function __invoke($request, callable $next) {
try {
return $next($request);
} catch (\Buzz\Exception\RequestException $e) {
return $next($request); // Retry
}
}
});
try {
$response = $browser->get('https://invalid.url');
} catch (\Buzz\Exception\RequestException $e) {
Log::error('Request failed:', ['error' => $e->getMessage()]);
}
0 (no limit). Explicitly set:
$client = new Curl($factory, ['timeout' => 30]);
$browser->setOption('max_redirects', 5);
libnghttp2.CookieMiddleware for persistent cookies:
$browser->addMiddleware(new \Buzz\Middleware\Cookie\CookieMiddleware());
sendAsyncRequest() is non-blocking. Use proceed() to fetch results.$multiClient->sendAsyncRequest($request, ['callback' => function ($response) {
if ($response->getStatusCode() >= 400) {
throw new \RuntimeException('Failed');
}
}]);
$response = $client->sendRequest($request, ['expose_curl_info' => true]);
$info = $response->getAttribute('curl_info');
$browser->addMiddleware(new \Buzz\Middleware\LoggerMiddleware(
new \Monolog\Logger('buzz')
));
if ($response->getStatusCode() !== 200) {
throw new \RuntimeException('Unexpected status: ' . $response->getStatusCode());
}
\Buzz\Middleware for request/response transformation:
$browser->addMiddleware(new class implements \Buzz\Middleware {
public function __invoke($request, callable $next) {
$request = $request->withHeader('X-My-Header', 'value');
return $next($request);
}
});
Psr17Factory to customize request/response creation.AbstractClient::configureOptions():
Curl::configureOptions(function (\Symfony\Component\OptionsResolver\OptionsResolver $resolver) {
$resolver->setDefaults(['timeout' => 10]);
});
$start = microtime(true);
$multiClient->sendAsyncRequest($request1);
$multiClient->sendAsyncRequest($request2);
$responses = $multiClient->proceed();
$duration = microtime(true) - $start;
MultiCurl for parallel HTTP jobs in queues:
$multiClient = new MultiCurl($factory);
foreach ($urls as $url) {
$multiClient->sendAsyncRequest($browser->createRequest('GET', $url));
}
$results = $multiClient->proceed();
$cacheKey = 'buzz:response:' . md5($url);
$response = Cache::get($cacheKey);
if (!$response) {
$response = $browser->get($url);
Cache::put($cacheKey, $response, now()->addHours(1));
}
How can I help you explore Laravel packages today?