Skip to content

useFetch API

New in v2.0.1

Async HTTP requests with parallel execution support

  • Simple & Powerful


    Fluent interface for HTTP requests with full async support

  • Highly Configurable


    Timeouts, SSL, headers, redirects - everything you need

  • Parallel Execution


    True concurrent requests with curl_multi for maximum performance

  • Modern PHP API


    Familiar syntax with modern PHP features

Namespace

<?php
use function Component\useFetch;

Basic Usage

Simple GET Request

<?php
// Auto-executes and returns decoded JSON
echo useFetch('https://api.example.com/users/1');
<?php
$user = useFetch('https://api.example.com/users/1');
echo $user['data']['first_name'];
<?php
$response = useFetch('https://api.example.com/users')
    ->get(['page' => 2, 'limit' => 10]);

HTTP Methods

<?php
useFetch('https://api.example.com/users')
    ->post(['name' => 'Dave', 'job' => 'Developer']);
<?php
useFetch('https://api.example.com/users/2')
    ->put(['job' => 'Senior Developer']);
<?php
useFetch('https://api.example.com/users/2')
    ->patch(['job' => 'Lead Developer']);
<?php
useFetch('https://api.example.com/users/2')
    ->delete(['force' => 'true']);

Configuration Options

Chain Before HTTP Method

All configuration methods must be called before ->get(), ->post(), etc.

<?php
$response = useFetch('https://api.example.com/users')
    ->headers(['Authorization' => 'Bearer token']) // (1)
    ->query(['page' => 2, 'limit' => 10]) // (2)
    ->form(['key' => 'value']) // (3)
    ->timeout(30)              // (4)
    ->connectTimeout(5)        // (5)
    ->verifySSL(true)          // (6)
    ->withCertificate('/path/to/cacert.pem') // (7)
    ->followRedirects(true, 5) // (8)
    ->withUserAgent('MyApp/1.0') // (9)
    ->unixSocket('/var/run/service.sock') // (10)
    ->get();
  1. Headers - Add custom headers (Authorization, API keys, etc.)
  2. Query Parameters - Attach query params to any HTTP method
  3. Form Data - Send form-encoded data with automatic Content-Type header
  4. Timeout - Request timeout in seconds (supports decimals like 0.5)
  5. Connect Timeout - Connection timeout in seconds (cURL only)
  6. SSL Verification - Enable/disable certificate verification
  7. CA Bundle - Path to custom certificate bundle (PEM format)
  8. Redirects - Follow redirects with max limit (cURL only)
  9. User Agent - Custom User-Agent string
  10. Unix Socket - Connect via Unix domain socket instead of TCP
  11. Resolve IP - Force request to resolve to a specific IP address
  12. Custom cURL Options - Pass raw CURLOPT_* options via ->withOptions([CURLOPT_* => ...]) (cURL only)

Request Body & Query Parameters

Query Parameters

Attach query parameters to any HTTP method (not just GET):

<?php

// Add query params to POST request
$response = useFetch('https://api.example.com/search')
                ->query(['page' => 2, 'limit' => 10])
                ->post(['term' => 'php']);

// Or use query string directly
$response = useFetch('https://api.example.com/search')
                ->query('page=2&limit=10')
                ->post(['term' => 'php']);

Form-Encoded Data

Send form-encoded data instead of JSON with automatic Content-Type header:

<?php

// Send form data (sets Content-Type: application/x-www-form-urlencoded)
$response = useFetch('https://api.example.com/login')
                ->form(['username' => 'dave', 'password' => 'secret'])
                ->post();

// Or use pre-encoded string
$response = useFetch('https://api.example.com/webhook')
                ->form('event=push&repo=phpspa')
                ->post();

JSON vs Form Data

By default, ->post(), ->put(), and ->patch() send data as JSON. Use ->form() when the API expects form-encoded data.

Custom cURL Options Examples

<?php

// Pass CURLOPT_* directly (advanced cURL-only options)
$res = useFetch('https://api.example.com/users')
    ->withOptions([
        CURLOPT_PROXY => 'http://127.0.0.1:8080',
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2TLS,
    ])
    ->get();
<?php

// Alternative form: nest under "curl" / "curl_options" (useful if you also pass PhpSPA options)
$res = useFetch('https://api.example.com/users')
    ->timeout(10)
    ->withOptions([
        'curl' => [
            'CURLOPT_PROXY' => 'http://127.0.0.1:8080',
        ],
    ])
    ->get();

Advanced Configuration Methods

Unix Socket Connection

Connect to services via Unix domain sockets instead of TCP:

<?php

// Connect to Docker daemon
$response = useFetch('http://localhost/containers/json')
                ->unixSocket('/var/run/docker.sock')
                ->get();

// Alternative method name
$response = useFetch('http://localhost/version')
                ->unixSocketPath('/var/run/docker.sock')
                ->get();

IP Resolution Override

Force requests to resolve to a specific IP address:

<?php

// Force example.com to resolve to specific IP
$response = useFetch('https://example.com/api')
                ->resolveIP('192.168.1.100')
                ->get();

Custom Certificate

Use a custom CA certificate bundle:

<?php

$response = useFetch('https://self-signed.example.com')
                ->withCertificate('/path/to/cacert.pem')
                ->get();

Custom User Agent

Set a custom User-Agent header:

<?php

$response = useFetch('https://api.example.com')
                ->withUserAgent('MyApp/2.0 (PHP)')
                ->get();

Redirect Control

Control redirect behavior (cURL only):

<?php

// Follow up to 5 redirects
$response = useFetch('https://api.example.com')
                ->followRedirects(true, 5)
                ->get();

// Disable redirects
$response = useFetch('https://api.example.com')
                ->followRedirects(false)
                ->get();

API Reference:

Method Parameters Description
unixSocket(string $path) Socket path Connect via Unix domain socket
unixSocketPath(string $path) Socket path Alias for unixSocket()
resolveIP(string $ip) IP address Force hostname to resolve to specific IP
withCertificate(string $path) PEM file path Use custom CA certificate bundle
withUserAgent(string $ua) User agent string Set custom User-Agent header
followRedirects(bool, int) Follow, Max count Control redirect behavior (cURL only)

Response Handling

<?php
$response = useFetch('https://api.example.com/users/2')->get();

$data = $response->json();      // (1)
$text = $response->text();      // (2)
$status = $response->status();  // (3)
$headers = $response->headers(); // (4)

if ($response->ok()) {          // (5)
    // Success handling
}

if ($response->failed()) {      // (6)
    echo $response->error();    // (7)
}
  1. Returns decoded JSON as associative array
  2. Returns raw response body as string
  3. Returns HTTP status code (200, 404, etc.)
  4. Returns response headers as array
  5. Checks if status is 200-299
  6. Checks if request failed
  7. Returns error message string

Asynchronous Requests

Requires cURL Extension

Async features only work when cURL is available. Falls back to sync execution otherwise.

Single Async Request

<?php
$promise = useFetch('https://api.example.com/users/1')->async()->get();

// Do other work here...

$response = $promise->wait();
echo $response->json()['name'];

True Concurrency

Execute multiple requests simultaneously using curl_multi for maximum performance!

<?php
use PhpSPA\Core\Client\AsyncResponse;

// Prepare requests
$user = useFetch('https://api.example.com/users/1')->async()->get();
$posts = useFetch('https://api.example.com/posts')->async()->get(['userId' => 1]);
$comments = useFetch('https://api.example.com/comments')->async()->get(['userId' => 1]);

// Execute all simultaneously
[$userRes, $postsRes, $commentsRes] = AsyncResponse::all([
    $user, $posts, $comments
]);

echo $userRes->json()['name'];
echo count($postsRes->json()) . " posts";
<?php
// Without AsyncResponse::all() - executes one by one
$user = $userPromise->wait()->json();
$posts = $postsPromise->wait()->json();
$comments = $commentsPromise->wait()->json();

With Callbacks

<?php
useFetch('https://api.example.com/users/1')
    ->async()
    ->get()
    ->then(fn($res) => print $res->json()['name'])
    ->wait();

Complete Examples

POST with Error Handling

<?php
$response = useFetch('https://api.example.com/users')
    ->headers(['Authorization' => 'Bearer token'])
    ->timeout(15)
    ->post(['name' => 'Dave', 'email' => 'dave@example.com']);

if ($response->ok()) {
    echo "✅ User created: " . $response->json()['id'];
} else {
    error_log('❌ API Error: ' . $response->error());
}

Parallel API Calls

<?php
use PhpSPA\Core\Client\AsyncResponse;

$requests = [
    useFetch('https://api.example.com/users/1')->async()->get(),
    useFetch('https://api.example.com/users/2')->async()->get(),
    useFetch('https://api.example.com/users/3')->async()->get(),
];

$responses = AsyncResponse::all($requests);

foreach ($responses as $res) {
    echo $res->json()['name'] . "\n";
}

Important Notes

Avoid Same-Server Requests

Never make HTTP requests to the same server handling the current request - it causes deadlock!

<?php
// ❌ Don't do this
$response = useFetch('http://localhost:8000/same-app-route')->get();

// ✅ Do this instead
$data = getSomeData();

Understanding Async Behavior

PHP is synchronous by nature. The async() method prepares cURL handles without executing them:

  • Use AsyncResponse::all() for true parallel execution with curl_multi
  • Sequential wait() calls execute requests one by one
  • Parallel execution is significantly faster for multiple requests