JavaScript-inspired fetch() for PHP 8.3+. Make HTTP requests with a
familiar entry point, backed by Guzzle. Use simple synchronous requests, or
opt into fluent configuration, retries, middleware, streaming, asynchronous
workflows, and PSR-7 / PSR-18 interoperability.
Fetch PHP takes inspiration from JavaScript Fetch, but it is not a browser Fetch API polyfill. It uses PHP values and Guzzle request options, and does not implement the browser Fetch security model.
- PHP 8.3 or newer
- Composer
- Runtime packages: Guzzle 7.9+, PSR-7 1.x/2.x, PSR-3 1.x/2.x/3.x, ReactPHP
event-loop and promise packages, and
jerome/matrix ^4.0 - The package does not require
ext-pcntl; PHP 8.3+ and Composer are needed.
composer require jerome/fetch-phpComposer autoloads the global helpers. In a standalone script, load
vendor/autoload.php.
After installing, this example makes a real network request to a public demo API (internet access required):
<?php
require __DIR__.'/vendor/autoload.php';
$response = fetch('https://jsonplaceholder.typicode.com/users/1');
echo $response->json()['name'];Want a deterministic example without a network connection? Use the built-in mock server in the quick start below. For production applications, do not trust unvalidated response data or URLs derived from user input.
This complete example uses the built-in fake server, so it runs without network access. Save it as a PHP file in the project root after installing the package.
<?php
declare(strict_types=1);
require __DIR__ . "/vendor/autoload.php";
use Fetch\Interfaces\Response as FetchResponse;
use Fetch\Testing\MockResponse;
use Fetch\Testing\MockServer;
MockServer::fake([
"GET https://api.example.test/v1/users/42" => MockResponse::json([
"id" => 42,
"name" => "Ada Lovelace",
]),
]);
MockServer::preventStrayRequests();
$response = fetch("https://api.example.test/v1/users/42");
if (!($response instanceof FetchResponse)) {
throw new RuntimeException("Expected a synchronous HTTP response.");
}
$user = $response->json();
echo $user["name"], PHP_EOL;Replace the fake with your service URL and remove the mock setup to make a real request. Keep URLs derived from untrusted input subject to your application's SSRF controls.
fetch($url, $options) makes one request. Passing no URL to fetch() returns
the ClientHandler for fluent configuration. fetch_client() returns the
shared Fetch\Http\Client facade; call getHandler() when you need
handler-only configuration.
$response = get("https://api.example.test/users", ["page" => 2]);
$created = post("https://api.example.test/users", ["name" => "Grace"]);
$updated = put("https://api.example.test/users/42", ["name" => "Grace Hopper"]);
$changed = patch("https://api.example.test/users/42", ["active" => false]);
$deleted = delete("https://api.example.test/users/42");The get() helper treats its second argument as query parameters. Array data
passed to post(), put(), patch(), or delete() is JSON by default. For
form or multipart data, pass form or multipart in fetch() options. See
making requests for
body, header, timeout, redirect, TLS, cookie, and proxy options.
| PHP entry point | Purpose |
|---|---|
fetch($url, $options) |
One request using an options array |
fetch_client() |
Shared object-oriented Client facade |
Fetch\Http\Client |
PSR-18 client plus convenience methods |
Fetch\Http\ClientHandler |
Fluent request configuration and execution |
Responses are PSR-7 responses extended by Fetch\Http\Response. Use status(),
isStatus(), successful(), and failed() for status checks; a 4xx or 5xx
response is not automatically an exception. Parse JSON with json(), read plain
text with text(), or inspect headers with header(). See the
response guide.
Fetch PHP integrates with Matrix 4 and ReactPHP promises. Use
ClientHandler::create()->async() for nonblocking buffered HTTP requests
through the default cURL multi transport. Matrix's all() and map() compose
concurrent requests; cancellation reaches the active transport and retry timers.
Custom Guzzle clients require an explicit loop-compatible AsyncTransport.
Wrapping a synchronous fetch() call in async() still blocks. See the
async guide for
transport configuration, cancellation, and timeouts.
The documentation site covers retries, HTTP caching, middleware, lifecycle events, streaming and SSE, HTTP/2 configuration and pool limits, logging and profiling, and offline testing.
The package implements PSR-7 HTTP messages, PSR-18 HTTP client behavior, and PSR-3 logger awareness. Optional JSON Schema and OpenAPI 3.0.x validation runs after request middleware and before responses are returned. Install the optional adapters described in the validation guide to enable it.
Install dependencies and run the repository checks:
composer install
composer check
composer docs:examples
npm ci
npm run build
npm run check-linkscomposer check runs PHPStan, Duster, and PHPUnit. Documentation PHP examples
are syntax-checked and the runnable fixtures execute against local fakes. See
CONTRIBUTING.md for contribution guidance and
the documentation site for the full guide
and API reference.
Report bugs and request features on GitHub Issues. For security reports, follow the private contact instructions in SECURITY.md.
Fetch PHP is available under the MIT License.