Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Curl Client Laravel Package

athlon1600/php-curl-client

Lightweight, extensible PHP cURL client (PHP 7.3–8.4). Make GET/POST or fully customized requests and always receive a standardized Response with status, body, error, and typed cURL info for IDE autocomplete.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require athlon1600/php-curl-client
    

    Ensure ext-curl and ext-json are enabled in your PHP environment.

  2. First Request:

    use Curl\Client;
    
    $client = new Client();
    $response = $client->get('https://api.example.com/data');
    
  3. Key Response Properties:

    • $response->status (HTTP status code)
    • $response->body (raw response body)
    • $response->error (curl error or null)
    • $response->info (CurlInfo object with metadata like headers, redirects, etc.)

First Use Case: API Consumption

$client = new Client();
$response = $client->get('https://api.github.com/users/octocat');

// Parse JSON response
$data = json_decode($response->body, true);

Implementation Patterns

1. Standardized HTTP Methods

Leverage convenience methods for common HTTP verbs:

// GET
$client->get('https://api.example.com/users');

// POST
$client->post('https://api.example.com/users', ['name' => 'John']);

// PUT/PATCH/DELETE
$client->put('https://api.example.com/users/1', ['name' => 'Updated']);
$client->delete('https://api.example.com/users/1');

2. Custom Requests

For non-standard requests (e.g., custom headers, proxies):

$client->request(
    'GET',
    'https://api.example.com/protected',
    null, // No body
    [
        'Authorization' => 'Bearer token123',
        'Accept' => 'application/json'
    ],
    [
        CURLOPT_PROXY => 'http://proxy.example.com:8080',
        CURLOPT_TIMEOUT => 30
    ]
);

3. Browser-Like Behavior

Use BrowserClient for session-like interactions (cookies, user-agent):

use Curl\BrowserClient;

$browser = new BrowserClient();
$browser->setUserAgent('Mozilla/5.0 (Windows NT 10.0)');
$browser->setStorageDirectory(storage_path('cookies')); // Persist cookies

// Subsequent requests share cookies
$browser->get('https://example.com/login');
$browser->post('https://example.com/login', ['email' => 'user@example.com']);

4. Error Handling

Validate responses in a Laravel service:

public function fetchData()
{
    $response = $client->get('https://api.example.com/data');

    if ($response->error) {
        throw new \RuntimeException("cURL Error: " . $response->error);
    }

    if ($response->status !== 200) {
        throw new \RuntimeException("HTTP Error: " . $response->status);
    }

    return json_decode($response->body, true);
}

5. Integration with Laravel HTTP Clients

Wrap the client for consistency with Laravel’s Http facade:

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->singleton('curl.client', function () {
        return new Client();
    });
}

// Usage in controllers
$response = app('curl.client')->get('https://api.example.com');

6. Testing

Mock responses in PHPUnit:

public function testApiCall()
{
    $client = new Client();
    $response = $client->get('https://api.example.com/data');

    $this->assertEquals(200, $response->status);
    $this->assertNotNull($response->body);
    $this->assertNull($response->error);
}

Gotchas and Tips

Pitfalls

  1. POST Redirects:

    • By default, CURLOPT_FOLLOWLOCATION converts POST to GET on 3xx redirects. To preserve the method, set:
      $client->request('POST', 'url', $data, [], [CURLOPT_POSTREDIR => 'FOLLOW']);
      
  2. Custom Options Override:

    • Ensure custom options override defaults by merging them after defaults:
      // Correct (from v1.1.2 fix)
      $customOptions + $defaultOptions
      
  3. Cookie Storage:

    • If using BrowserClient, ensure the storage directory is writable:
      $browser->setStorageDirectory(storage_path('framework/sessions'));
      
  4. IDE Autocomplete:

    • $response->info returns a CurlInfo object with IDE-friendly properties (e.g., info->http_code, info->url).
  5. HTTPBin Redirects:

    • Avoid httpbin.org/redirect-to in tests (broken endpoint; use workarounds).

Debugging Tips

  1. Inspect cURL Info:

    dump($response->info->__toArray()); // Full cURL metadata
    
  2. Enable Verbose Output:

    $client->request('GET', 'url', null, [], [CURLOPT_VERBOSE => true]);
    
  3. Check for Redirects:

    if ($response->info->redirect_count > 0) {
        logger()->debug("Redirected to: " . $response->info->url);
    }
    

Extension Points

  1. Custom Response Handling: Extend the Client class to add middleware:

    class CustomClient extends Client
    {
        public function request($method, $url, $data = null, $headers = [], $options = [])
        {
            // Pre-process request
            $response = parent::request($method, $url, $data, $headers, $options);
    
            // Post-process response
            if ($response->status === 401) {
                $this->reauthenticate();
            }
    
            return $response;
        }
    }
    
  2. PSR-18 Compatibility (Future-Proofing): Monitor the TODO in the README for PSR-7/PSR-18 updates. For now, wrap responses:

    use Psr\Http\Message\ResponseInterface;
    
    $psrResponse = new class($response) implements ResponseInterface {
        public function __construct(private $rawResponse) {}
        public function getBody() { return new Stream($this->rawResponse->body); }
        // Implement other PSR-7 methods...
    };
    
  3. Retry Logic: Add exponential backoff for transient failures:

    public function getWithRetry($url, $maxRetries = 3)
    {
        $retries = 0;
        while ($retries < $maxRetries) {
            $response = $client->get($url);
            if ($response->status !== 503) break;
            sleep(2 ** $retries);
            $retries++;
        }
        return $response;
    }
    

Configuration Quirks

  1. Default Options: Override globally via constructor:

    $client = new Client([
        CURLOPT_TIMEOUT => 10,
        CURLOPT_SSL_VERIFYPEER => false // Disable for testing only!
    ]);
    
  2. User-Agent Spoofing: Use BrowserClient or set headers:

    $client->request('GET', 'url', null, ['User-Agent' => 'MyApp/1.0']);
    
  3. SSL Verification: Disable only in development:

    $client->request('GET', 'url', null, [], [CURLOPT_SSL_VERIFYPEER => false]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui