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

Discovery Laravel Package

php-http/discovery

Auto-discovery for HTTP clients and factories: finds PSR-18 clients and PSR-17/PSR-7 implementations at runtime, so libraries can depend on interfaces without forcing a specific vendor. Includes a Composer plugin for optional auto-installation.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package:

    composer require php-http/discovery
    

    This adds the discovery layer to your project—no runtime dependencies required.

  2. Immediate use case (library author):
    In your package, inject HTTP client without binding to a concrete implementation:

    use Http\Discovery\Psr18Client;
    
    $client = Psr18Client::create();
    

    Internally, it auto-selects a PSR-18 client (e.g., guzzlehttp/guzzle, symfony/http-client) and matching PSR-17 factories.

  3. Check supported implementations:
    Run composer show | grep -E '(psr-18|psr-7|psr-17)' to see what implementations you already have.

Implementation Patterns

  • Avoid hard dependencies in libraries:
    Require only php-http/discovery and PSR interface psr/http-client:

    {
      "require": {
        "php-http/discovery": "^1.17",
        "psr/http-client": "^1.0"
      }
    }
    

    Let users install their preferred client (e.g., guzzlehttp/guzzle:^7.0, symfony/http-client:^6.0).

  • Use discovery-aware classes in app code (for prototyping or small apps):

    use Http\Discovery\Psr18Client;
    use Http\Discovery\Psr17Factory;
    
    $client = Psr18Client::create();
    $requestFactory = Psr17Factory::createServerRequestFactory();
    $request = $requestFactory->createServerRequest('GET', 'https://api.example.com');
    $response = $client->sendRequest($request);
    
  • Configure preferred implementations (for apps where you control dependencies):

    composer config extra.discovery.psr/http-client-implementation GuzzleHttp\\Client::class
    composer config extra.discovery.psr/http-factory-implementation GuzzleHttp\\Psr7\\HttpFactory::class
    

    Then run composer install to let the plugin auto-install missing deps if enabled.

  • Disable auto-installation in dev (to avoid surprising dependency resolution):

    composer config allow-plugins.php-http/discovery false
    

Gotchas and Tips

  • Composer plugin may auto-install dependencies unless disabled or a suitable candidate exists. This can break lockfile reproducibility—always composer update after changing extra.discovery.* config.

  • Multiple implementations conflict:
    If you have nyholm/psr7 and guzzlehttp/psr7 installed, discovery picks one arbitrarily. Pin one explicitly using extra.discovery to avoid flaky behavior.

  • Psr18Client vs direct HttpClientDiscovery:
    Prefer Psr18Client (simple, modern) over legacy HttpClientDiscovery, which is deprecated in v1.18.0+.

  • No runtime dependency ≠ zero cost:
    Discovery scans installed packages at runtime using reflection—usually negligible, but avoid using it in hot paths (e.g., per-request in CLI tools). Cache discovery results or wire clients via DI instead.

  • Magento/Laminas compatibility:
    Use ClassDiscovery::safeClassExists() instead of raw class_exists() in legacy environments to avoid autoloader conflicts.

  • Debugging discovery failures:
    Wrap discovery calls in try/catch(Http\Discovery\Exception\DiscoveryFailedException $e) to list candidates that were skipped:

    try {
        $client = Psr18Client::create();
    } catch (\Http\Discovery\Exception\DiscoveryFailedException $e) {
        error_log('No client found. Candidates: ' . print_r($e->getCandidates(), true));
    }
    
  • Testing tip:
    For unit tests, disable discovery by mocking Psr18Client or use Http\Discovery\Strategy\MockClientStrategy (v1.2.0+) to inject test doubles deterministically.

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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport