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 Components Laravel Package

league/uri-components

Immutable value-object URI components for PHP. Build, validate, normalize and convert parts like scheme, authority, host, path, query and fragment with PSR-7 compatibility. Supports IDN hosts (intl/polyfill) and IPv4 conversion.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require league/uri-components
    

    Requires PHP 8.1+ and extensions like intl for IDN support (or a polyfill).

  2. First Use Case: Parse and manipulate a URL:

    use League\Uri\Components\Uri;
    use League\Uri\Components\Query;
    
    $uri = Uri::create('https://example.com/search?q=laravel&page=1');
    $query = $uri->query();
    
    // Access query parameters
    $searchTerm = $query->get('q'); // 'laravel'
    $page = $query->get('page');   // '1'
    
    // Modify query
    $modifiedQuery = $query->with('page', 2);
    $modifiedUri = $uri->withQuery($modifiedQuery);
    
  3. Key Classes to Explore:

    • Uri: Root class for URI manipulation.
    • Query: Handle query strings (e.g., ?key=value).
    • Modifier: Chainable URI modifications (e.g., appending paths, modifying queries).
    • Domain, Path, Fragment: Component-specific classes.

Implementation Patterns

Common Workflows

1. URI Construction and Parsing

// Parse from string
$uri = Uri::create('https://api.example.com/v1/users');

// Build from components
$uri = Uri::create()
    ->withScheme('https')
    ->withHost('api.example.com')
    ->withPath('/v1/users');

2. Query String Manipulation

$query = Query::createFrom('?sort=desc&limit=10');

// Add/Modify Parameters
$query->with('limit', 20)->with('filter', 'active');

// Remove Parameters
$query->without('filter');

// Convert to array
$params = $query->toArray();

3. URL Modification with Modifier

$modifier = Modifier::createFrom('https://example.com');
$modifiedUri = $modifier
    ->appendPath('/api/v1')
    ->appendQueryPairs(['page' => 1, 'sort' => 'asc'])
    ->toUri();

4. Domain and Path Operations

$domain = Domain::createFrom('sub.example.com');
$domain->isSubdomainOf('example.com'); // true

$path = Path::create('/api/v1/users');
$path->append('/profile'); // '/api/v1/users/profile'

5. Integration with Laravel

  • Request Handling:
    use League\Uri\Components\Uri;
    use Illuminate\Http\Request;
    
    $requestUri = Uri::create(request()->getUri());
    $query = $requestUri->query();
    
  • Redirects:
    return redirect()->to(
        Modifier::createFrom('/dashboard')
            ->appendQueryPairs(['tab' => 'settings'])
            ->toString()
    );
    

6. Validation and Sanitization

$uri = Uri::create('https://example.com');
$uri->isValid(); // true

$uri->withHost('invalid host'); // Throws exception if invalid

Integration Tips

Laravel Service Provider

Register a helper for URI manipulation:

// app/Providers/AppServiceProvider.php
use League\Uri\Components\Uri;
use Illuminate\Support\Facades\Blade;

public function boot()
{
    Blade::directive('uri', function ($expression) {
        return "<?php echo (string) League\Uri\Components\Uri::create({$expression}); ?>";
    });
}

Form Request Validation

use League\Uri\Components\Uri;
use Illuminate\Validation\Rule;

$validator->addRules([
    'url' => [
        'required',
        function ($attribute, $value, $fail) {
            if (!Uri::create($value)->isValid()) {
                $fail('The '.$attribute.' must be a valid URL.');
            }
        },
    ],
]);

API Response Manipulation

use League\Uri\Components\Modifier;

return response()->json($data, 200, [
    'Location' => Modifier::createFrom('/api/resource/123')
        ->appendQueryPairs(['action' => 'update'])
        ->toString(),
]);

Gotchas and Tips

Pitfalls

  1. Immutable Objects:

    • All components (e.g., Query, Path) are immutable. Use modifier methods (e.g., with(), append()) to create new instances.
    • Anti-pattern:
      $query->set('key', 'value'); // ❌ Throws error (no setter)
      
    • Fix:
      $newQuery = $query->with('key', 'value'); // ✅ Correct
      
  2. Query String Encoding:

    • Use Query::encoded() or Query::decoded() for raw string manipulation.
    • Gotcha: Query::toString() always returns URL-encoded output.
      $query = Query::createFrom('?key=value with spaces');
      $query->toString(); // 'key=value+with+spaces'
      $query->decoded();  // 'key=value with spaces'
      
  3. Domain Handling:

    • Domain::createFrom() throws exceptions for invalid domains (e.g., example..com).
    • Use tryNew() for safe creation:
      $domain = Domain::tryNew('invalid..domain'); // Returns null
      
  4. Path Segments:

    • Leading/trailing slashes are normalized automatically:
      Path::create('/api//users')->toString(); // '/api/users'
      
  5. Query Parameter Order:

    • Query::sort() ensures WHATWG compliance (alphabetical order by key).
    • Use Query::unsorted() to preserve insertion order.
  6. IPv4/IPv6 Hosts:

    • Requires GMP, BCMath, or 64-bit PHP for IPv4 conversion.
    • Fix: Install extensions or use a polyfill like symfony/polyfill-php80.

Debugging Tips

  1. Inspect Components:

    $uri = Uri::create('https://example.com/path?query=value');
    dump($uri->scheme()); // 'https'
    dump($uri->host());   // 'example.com'
    dump($uri->query());  // Query object
    
  2. Validate URIs:

    if (!$uri->isValid()) {
        throw new \InvalidArgumentException('Invalid URI');
    }
    
  3. Handle Exceptions:

    • Catch League\Uri\Exception\SyntaxError for malformed URIs.
    • Catch League\Uri\Exception\RuntimeException for runtime issues (e.g., missing extensions).
  4. Query Debugging:

    $query = Query::createFrom('?key=value&key=other');
    $query->all(); // ['key' => ['value', 'other']]
    $query->get('key'); // ['value', 'other'] (array for multiple values)
    

Extension Points

  1. Custom Query Parsing: Override Query::fromString() or use Query::fromPairs() for custom formats:

    $query = Query::fromPairs(['custom_key' => 'custom_value']);
    
  2. Domain Logic: Extend Domain for custom subdomain checks:

    $domain = Domain::createFrom('api.example.com');
    $domain->isSubdomainOf('example.com'); // true
    
  3. Modifier Chaining: Create custom modifiers:

    $modifier = Modifier::createFrom('/base')
        ->appendPath('/custom')
        ->appendQueryPairs(['debug' => true]);
    
  4. PSR-7 Integration: Convert to/from PSR-7 UriInterface:

    use League\Uri\Components\Modifier;
    use Psr\Http\Message\UriInterface;
    
    $psr7Uri = new \GuzzleHttp\Psr7\Uri('https://example.com');
    $modifier = Modifier::wrap($psr7Uri);
    
  5. BackedEnum Support: Use BackedEnum for type-safe schemes/ports:

    use League\Uri\Components\Scheme;
    
    $scheme = Scheme::from('https'); // Returns BackedEnum instance
    $scheme->value(); // 'https'
    

Performance Considerations

  1. Avoid Repeated Parsing: Cache parsed URIs if reused frequently:

    static $cachedUri = null;
    if (!$cachedUri) {
        $cachedUri = Uri::create('https://example.com');
    }
    
  2. Query Operations:

    • Prefer `Query::
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