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 objects for URI components (host, path, query, etc.) from The PHP League. PHP 8.1+. Supports IDN hosts (intl or polyfill) and IPv4 conversion (GMP/BCMath/64-bit). Built atop league/uri, uri-interfaces, and PSR-7.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require league/uri-components
    

    Requires PHP 8.1+ and intl extension (or symfony/polyfill-intl-idn) for IDN support.

  2. First Use Case: Parse and manipulate a URI in a Laravel controller or service:

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

    • Uri (root class for URI manipulation)
    • Query (for query string handling)
    • Modifier (for fluent URI modifications)
    • Domain, Path, Fragment (for granular component access)

Implementation Patterns

Common Workflows

1. URI Construction from Requests

Parse incoming HTTP requests (e.g., from Laravel's Request object):

use League\Uri\Components\Uri;
use Illuminate\Http\Request;

$request = app(Request::class);
$uri = Uri::createFromString($request->getUri());

// Extract query parameters
$query = $uri->query();
$filters = $query->all(); // Associative array of all query params

2. Fluent URI Modification

Use Modifier for chainable URI updates:

use League\Uri\Components\Modifier;

$uri = Uri::createFromString('https://api.example.com/v1/users');
$modifiedUri = Modifier::from($uri)
    ->withPath('/v2/users/123')
    ->withQuery('sort', 'desc')
    ->withFragment('section-1')
    ->toUri();

3. Query Parameter Handling

Leverage Query methods for complex query logic:

$query = Query::fromString('?id=1&tags[]=php&tags[]=laravel');

// Check for list parameters
if ($query->hasList('tags')) {
    $tags = $query->getList('tags'); // ['php', 'laravel']
}

// Filter and transform
$filtered = $query->filter(fn($key, $value) => str_contains($key, 'tag'));

4. Domain and Path Manipulation

Work with subdomains or path segments:

$domain = $uri->domain();
if ($domain->isSubdomainOf('example.com')) {
    $subdomain = $domain->first(); // 'api'
}

$path = $uri->path();
$segments = $path->segments(); // ['v1', 'users']
$newPath = $path->withSegments(['v2', 'users', '123']);

5. Integration with Laravel Routes

Generate URIs for named routes dynamically:

use Illuminate\Support\Facades\Route;

$routeUri = Route::getUriFor('users.show', ['user' => 123]);
$uri = Uri::createFromString($routeUri);

// Append query params
$uriWithParams = $uri->withQuery('with', 'profile');

6. Validation and Sanitization

Ensure URI components are valid before use:

$uri = Uri::createFromString($userInput);
if (!$uri->isValid()) {
    throw new \InvalidArgumentException('Invalid URI');
}

// Normalize components
$normalizedHost = $uri->host()->normalized();

Integration Tips

Laravel Service Providers

Bind the package for dependency injection:

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->bind(Uri::class, function () {
        return Uri::createFromString(request()->getUri());
    });
}

Form Request Validation

Validate URI components in Laravel form requests:

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

public function rules()
{
    return [
        'callback_url' => [
            'required',
            function ($attribute, $value, $fail) {
                $uri = Uri::createFromString($value);
                if (!$uri->isValid() || !$uri->scheme()->isHttp()) {
                    $fail('The '.$attribute.' must be a valid HTTP URL.');
                }
            },
        ],
    ];
}

API Response Generation

Construct paginated API responses with query parameters:

$uri = Uri::createFromString(request()->getUri());
$nextPageUri = $uri->withQuery('page', $currentPage + 1);

return response()->json([
    'data' => $users,
    'links' => [
        'next' => $nextPageUri->toString(),
    ],
]);

Testing

Use the package to assert URI behavior in tests:

use League\Uri\Components\Uri;
use Tests\TestCase;

public function testUriConstruction()
{
    $uri = Uri::createFromString('https://example.com/path?query=value');
    $this->assertEquals('example.com', $uri->host()->toString());
    $this->assertEquals('value', $uri->query()->get('query'));
}

Gotchas and Tips

Pitfalls

1. Immutable Objects

All components (e.g., Query, Domain) are immutable. Always use modifier methods (e.g., with(), append()) to create new instances:

// ❌ Wrong: Attempting to mutate
$query->set('key', 'value'); // Throws error

// ✅ Correct: Create a new instance
$newQuery = $query->with('key', 'value');

2. Query String Parsing Quirks

  • List Parameters: Use getList() for multi-value parameters (e.g., ?tags[]=php&tags[]=laravel).
  • Case Sensitivity: Query keys are case-sensitive by default. Use Query::fromString() with $coercionMode to normalize:
    $query = Query::fromString('?Key=Value', Query::COERCION_MODE_LOWERCASE);
    $query->get('key'); // 'Value'
    

3. IDN and Host Handling

  • Ensure the intl extension is installed for Internationalized Domain Names (IDN).
  • Use Host::normalized() to convert between IDN and ASCII:
    $host = $uri->host();
    $asciiHost = $host->normalized(); // 'xn--example-123.com'
    

4. Path Segments and Slashes

  • Path segments are not automatically joined with slashes. Use HierarchicalPath for proper handling:
    $path = HierarchicalPath::createFromString('/api/v1/users');
    $segments = $path->segments(); // ['api', 'v1', 'users']
    
    // Append a segment
    $newPath = $path->withSegments(['api', 'v1', 'users', '123']);
    

5. Deprecated Methods

  • Avoid deprecated methods like Modifier::from() (use Modifier::wrap() instead).
  • Check the changelog for deprecated APIs.

6. IPv6 and Port Handling

  • IPv6 addresses require PHP 64-bit or GMP/BCMath extensions.
  • Ports are scheme-dependent. Use Port::defaultScheme() to check defaults:
    $port = $uri->port();
    if ($port->isDefaultForScheme($uri->scheme())) {
        // Port is implicit (e.g., :80 for HTTP)
    }
    

Debugging Tips

1. Inspect Components

Use toString() or debug() for debugging:

$uri = Uri::createFromString('https://example.com');
dd($uri->domain()->toString()); // 'example.com'

2. Query String Extraction Modes

Customize how query strings are parsed/composed:

$query = Query::fromString('?q=test', Query::EXTRACT_MODE_RFC3986);
$query->toString(Query::COMPOSE_MODE_RFC3986);

3. Validation Errors

Catch UriException for invalid URIs:

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.
croct/coding-standard
croct/plug-php
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php
trappistes/laravel-custom-fields
splash/sonata-admin
splash/metadata