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

Uri Interfaces Laravel Package

league/uri-interfaces

Interface definitions for RFC 3986-compliant URI objects. Targets PHP 8.1+, with optional intl (or polyfill) for IDN handling and GMP/BCMath or 64-bit PHP for IPv4 conversion. Part of the League URI project; docs at uri.thephpleague.com.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require league/uri-interfaces
    

    Requires PHP 8.1+ and extensions like intl (for IDN) or GMP/BCMath (for IPv4/IPv6).

  2. First Use Case: Parse a URI string into components:

    use League\Uri\Contracts\UriInterface;
    use League\Uri\UriString;
    
    $uriString = new UriString('https://example.com/path?query=value');
    $uri = $uriString->parse(); // Returns UriInterface
    
  3. Key Classes to Explore:

    • UriString: Parses/validates URI strings.
    • UriInterface: Core URI contract (scheme, host, path, etc.).
    • QueryString: Handles query parameters.
    • HostRecord: Normalizes host resolution (e.g., example.com).

Implementation Patterns

1. URI Parsing and Validation

  • Pattern: Use UriString for parsing and validation.
    $uriString = new UriString('https://user:pass@example.com:8080/path?query=value#frag');
    $uri = $uriString->parse(); // Throws \League\Uri\Exception\SyntaxError if invalid
    
  • Validation:
    if ($uriString->isValid()) {
        $uri = $uriString->parse();
    }
    

2. Query Parameter Handling

  • Pattern: Use QueryString for query manipulation.
    $query = new QueryString('key1=value1&key2=value2');
    $query->addPair('key3', 'value3'); // Adds a new pair
    $query->withoutPairByKey('key1');   // Removes a pair
    $queryString = $query->toString();  // 'key2=value2&key3=value3'
    
  • Form Data Conversion:
    $formData = ['key1' => 'value1', 'key2' => ['sub1', 'sub2']];
    $query = QueryString::fromFormData($formData);
    

3. Host and Domain Logic

  • Pattern: Use HostRecord for host normalization and domain checks.
    $host = new HostRecord('sub.example.com');
    $host->isSubdomainOf('example.com'); // true
    $host->parentHost(); // 'example.com'
    
  • IPv4/IPv6 Conversion:
    use League\Uri\IPv4\Converter;
    use League\Uri\IPv6\Converter;
    
    $ipv4 = Converter::toDecimal('192.168.1.1'); // 3232235777
    $ipv6 = Converter::normalize('2001:db8::1');  // '2001:db8:0:0:0:0:0:1'
    

4. URI Resolution and Relativization

  • Pattern: Resolve relative URIs against a base URI.
    $baseUri = (new UriString('https://example.com/base/'))->parse();
    $relativeUri = (new UriString('subpath'))->parse();
    $resolvedUri = $baseUri->resolve($relativeUri); // 'https://example.com/base/subpath'
    
  • Relativization:
    $resolvedUri->relativize($baseUri); // 'subpath'
    

5. Encoding/Decoding Components

  • Pattern: Use Encoder for component-specific encoding.
    use League\Uri\Encoder;
    
    $encoder = new Encoder();
    $encodedPath = $encoder->encodePath('/path with spaces'); // '/path%20with%20spaces'
    $decodedPath = $encoder->decodePath($encodedPath);       // '/path with spaces'
    

6. Integration with Laravel

  • Pattern: Use interfaces for dependency injection (e.g., in service containers).
    // In a Laravel service provider:
    $this->app->bind(
        UriInterface::class,
        fn() => (new UriString(request()->fullUrl()))->parse()
    );
    
  • Request/Response Handling:
    use League\Uri\Contracts\UriInterface;
    
    $uri = app(UriInterface::class);
    $query = $uri->getQuery(); // QueryString object
    

7. Testing URIs

  • Pattern: Mock UriInterface for unit tests.
    $mockUri = Mockery::mock(UriInterface::class);
    $mockUri->shouldReceive('getScheme')->andReturn('https');
    $mockUri->shouldReceive('getHost')->andReturn('example.com');
    

Gotchas and Tips

Pitfalls

  1. IDN (Internationalized Domain Names):

    • Requires intl extension or symfony/polyfill-intl-idn.
    • Throws League\Uri\Exception\MissingFeature if unsupported.
    • Fix: Install polyfill:
      composer require symfony/polyfill-intl-idn
      
  2. IPv4/IPv6 Conversion:

    • Requires GMP, BCMath, or 64-bit PHP.
    • Throws League\Uri\Exception\ConversionFailed if unsupported.
    • Fix: Upgrade PHP or install extensions.
  3. Query String Parsing:

    • QueryString::extract() may behave unexpectedly with malformed input (e.g., key=value&key=).
    • Tip: Use QueryComposeMode::RFC3986 for strict RFC compliance.
  4. Host Validation:

    • HostRecord::isValid() rejects IPv4/IPv6 without ports (e.g., 192.168.1.1 is invalid; 192.168.1.1:80 is valid).
    • Workaround: Use HostType::IPV4 or HostType::IPV6 explicitly.
  5. Deprecated Methods:

    • Avoid UriInterface::getComponents() (use toComponents() instead).
    • Avoid QueryInterface::withoutPair() (use withoutPairByKey()).
  6. Stringable Support:

    • Some methods (e.g., UriString::parseAuthority()) accept Stringable objects (PHP 8.0+).
    • Tip: Pass Stringable objects directly without casting to strings.
  7. Caching:

    • HostRecord caches DNS resolutions. Clear cache manually if needed:
      $hostRecord = new HostRecord('example.com');
      $hostRecord->clearCache();
      

Debugging Tips

  1. Validate URIs Early:

    if (!$uriString->isValid()) {
        throw new \InvalidArgumentException('Invalid URI: ' . $uriString->getError());
    }
    
  2. Inspect Components:

    $uri = $uriString->parse();
    dd($uri->toComponents()); // Associative array of all components
    
  3. Query Debugging:

    • Use QueryString::toFormData() to inspect parsed query parameters:
      $query = new QueryString('key1=value1&key2[]=val1&key2[]=val2');
      dd($query->toFormData());
      // Output: ['key1' => 'value1', 'key2' => ['val1', 'val2']]
      
  4. Host Debugging:

    • Check host type and format:
      $host = new HostRecord('example.com');
      dd($host->getType(), $host->getFormat());
      

Extension Points

  1. Custom Query Composers:

    • Extend QueryString by implementing QueryComposeMode:
      $query = new QueryString('key=value');
      $query->compose(['key' => 'newValue'], QueryComposeMode::RFC3986);
      
  2. Custom Encoders:

    • Implement League\Uri\Contracts\EncoderInterface for custom encoding rules.
  3. Domain Logic:

    • Extend DomainHostInterface for custom domain checks (e.g., TLD validation):
      class CustomDomainHost implements DomainHostInterface {
          public function isValid(): bool {
              // Custom validation logic
          }
      }
      
  4. URI Normalization:

    • Override UriInterface::toNormalizedString() for project-specific normalization.

Performance Tips

  1. Cache Host Resolutions:

    • HostRecord caches DNS lookups. Reuse instances for repeated host checks.
  2. Avoid Parsing Repeatedly:

    • Parse URIs once and reuse the UriInterface object:
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope