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

RFC 3986-compliant URI interfaces for PHP 8.1+. Defines contracts for URI objects and related components used across the League URI ecosystem. Supports IDN hosts (intl or polyfill) and IPv4 conversion (GMP/BCMath/64-bit).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require league/uri-interfaces
    

    Ensure PHP ≥ 8.1 and required extensions (intl, GMP, or BCMath) are installed.

  2. First Use Case: Validate a URI string or parse it 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
    
    // Access components
    echo $uri->getScheme(); // "https"
    echo $uri->getHost();   // "example.com"
    
  3. Key Classes to Explore:

    • UriString: Parse/validate strings.
    • UriInterface: Core URI operations (e.g., resolve(), relativize()).
    • QueryString: Parse/query string manipulation.
    • HostRecord: Validate/normalize hosts (e.g., isValid(), isSubdomainOf()).

Implementation Patterns

1. URI Parsing and Validation

  • Workflow:
    $uriString = new UriString($rawUri);
    if ($uriString->isValid()) {
        $uri = $uriString->parse();
        // Work with $uri (UriInterface)
    }
    
  • Validation:
    $uriString->isValidScheme('https'); // Check scheme validity
    $uriString->isValidHost('example.com'); // Validate host
    

2. Query String Manipulation

  • Extract/Compose:
    $query = new QueryString('key=value&foo=bar');
    $query->compose(['new_key' => 'new_value']); // Build query string
    $query->extract(); // Parse into key-value pairs
    
  • Form Data:
    $query->toFormData(); // Convert to array
    QueryString::fromFormData(['key' => 'value']); // Create from array
    

3. URI Resolution and Relativization

  • Resolve Relative URIs:
    $baseUri = (new UriString('https://example.com/base'))->parse();
    $relativeUri = (new UriString('path/to/resource'))->parse();
    $resolved = $baseUri->resolve($relativeUri); // Full URI
    
  • Relativize:
    $baseUri->relativize($resolvedUri); // Relative path
    

4. Host and Domain Operations

  • Subdomain Checks:
    $host = new HostRecord('sub.example.com');
    $host->isSubdomainOf('example.com'); // true
    
  • IPv4/IPv6 Conversion:
    use League\Uri\IPv4\Converter;
    Converter::toIPv6Using6to4('192.168.1.1'); // IPv6 representation
    

5. Encoding/Decoding Components

  • Normalize Encoding:
    $encoder = new Encoder();
    $encoder->normalizePath('/path with spaces'); // RFC3986-encoded
    
  • Decode Necessary:
    $encoder->decodeNecessary('%20'); // Decodes to ' '
    

6. Integration with Laravel

  • Request/Response Handling:
    use Illuminate\Http\Request;
    $uri = new UriString(request()->getUri());
    // Manipulate URI components before processing.
    
  • Route Generation:
    $uri = route('profile', ['user' => 'john']);
    $uriString = new UriString($uri);
    // Validate or modify before redirecting.
    

7. Testing URIs

  • Assertions:
    $this->assertTrue($uriString->isValid());
    $this->assertEquals('https', $uri->getScheme());
    $this->assertEquals(['key' => 'value'], $query->extract());
    

Gotchas and Tips

Pitfalls

  1. IDN Hosts Without intl Extension:

    • Throws MissingFeature if intl or a polyfill (e.g., symfony/polyfill-intl-idn) is missing.
    • Fix: Install intl or add the polyfill to composer.json:
      composer require symfony/polyfill-intl-idn
      
  2. IPv4 Conversion Requirements:

    • Requires GMP, BCMath, or 64-bit PHP. Throws ConversionFailed otherwise.
    • Fix: Enable extensions or upgrade PHP.
  3. Query String Parsing Quirks:

    • QueryString::extract() may misparse malformed queries (e.g., key=&value).
    • Tip: Use QueryComposeMode::STRICT for strict parsing:
      $query->extract(QueryExtractMode::STRICT);
      
  4. Host Validation Strictness:

    • HostRecord::isValid() rejects IPv4 addresses without port numbers (e.g., 192.168.1.1).
    • Tip: Use HostType::IPV4 for explicit validation:
      $host->isValid(HostType::IPV4);
      
  5. URI Resolution Edge Cases:

    • UriInterface::resolve() may fail with circular references or malformed URIs.
    • Debug: Check isValid() before resolving.
  6. Deprecated Methods:

    • Avoid UriInterface::getComponents() (use toComponents()).
    • Avoid QueryInterface::withoutPair() (use withoutPairByKey()).

Debugging Tips

  1. Component Inspection:

    $uri->toComponents(); // Associative array of all components
    $uri->toNormalizedString(); // Canonical string representation
    
  2. Query String Debugging:

    $query->composeFromValue(['key' => ['nested' => 'value']], QueryComposeMode::STRICT);
    // Outputs: key[nested]=value
    
  3. Host Resolution:

    $host = new HostRecord('example.com');
    $host->isValid(); // true
    $host->encoded(); // RFC3986-encoded host
    

Extension Points

  1. Custom Query Composition:

    • Extend QueryString by implementing QueryComposeMode enums for custom separators/encodings.
  2. Host Validation Logic:

    • Override HostRecord::isValid() for custom domain rules (e.g., allow local IPs).
  3. URI Normalization:

    • Implement Transformable for custom URI transformations (e.g., rewrite schemes).
  4. Encoding Strategies:

    • Create a custom Encoder subclass to override normalization rules.

Performance Notes

  • Host Resolution Caching: HostRecord caches DNS lookups. Disable with:
    $host = new HostRecord('example.com', false); // Disable caching
    
  • Query Parsing: Use QueryExtractMode::LOOSE for faster (but less strict) parsing.

Laravel-Specific Tips

  1. Middleware URI Manipulation:

    public function handle(Request $request, Closure $next) {
        $uri = new UriString($request->getUri());
        if ($uri->getHost() === 'admin.example.com') {
            $uri->withHost('internal-admin.example.com');
            $request->setRequestUri($uri->toString());
        }
        return $next($request);
    }
    
  2. Route Model Binding:

    public function bindRequest(Route $route, $value) {
        $uri = new UriString($value);
        return User::where('slug', $uri->getPath())->firstOrFail();
    }
    
  3. API Response URIs:

    return response()->json($data, 200, [
        'Location' => (new UriString(url('/resource')))->toString()
    ]);
    
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