Installation:
composer require egyg33k/domain-parser-bundle
Add the bundle to config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3-):
// config/bundles.php
Egyg33k\DomainParserBundle\Egyg33kDomainParserBundle::class => ['all' => true],
Or (Symfony 3-):
// AppKernel.php
new Egyg33k\DomainParserBundle\Egyg33kDomainParserBundle(),
First Use Case: Inject the parser via dependency injection (recommended) or fetch from the container:
use Egyg33k\DomainParserBundle\Parser\DomainParser;
// In a controller/service:
public function __construct(DomainParser $parser) {
$this->parser = $parser;
}
// Parse a URL string:
$url = $this->parser->parseUrl('https://user:pass@example.com/path?query=1#frag');
URL Parsing in Controllers:
public function handleRequest(Request $request, DomainParser $parser) {
$url = $parser->parseUrl($request->getUri());
$domain = $url->getHost(); // e.g., 'example.com'
// Use domain for logic (e.g., routing, analytics).
}
Validation & Sanitization:
$url = $parser->parseUrl($userInput);
if (!$url->isValid()) {
throw new \InvalidArgumentException('Invalid URL');
}
Extracting Components:
$url = $parser->parseUrl('https://sub.example.com:8080/path/to/page');
$components = [
'scheme' => $url->getScheme(), // 'https'
'host' => $url->getHost(), // 'sub.example.com'
'port' => $url->getPort(), // 8080
'path' => $url->getPath(), // '/path/to/page'
'query' => $url->getQuery(), // null
'fragment' => $url->getFragment(), // null
];
Rebuilding URLs:
$url = $parser->parseUrl('https://example.com');
$url->setPath('/new-path')->setQuery(['param' => 'value']);
$rebuiltUrl = $url->__toString(); // 'https://example.com/new-path?param=value'
$builder->add('website', UrlType::class, [
'constraints' => [
new Url(),
new Callback([$parser, 'validateUrl']),
],
]);
KernelEvents::REQUEST to inspect incoming requests:
public function onKernelRequest(GetResponseEvent $event) {
$url = $this->parser->parseUrl($event->getRequest()->getUri());
// Log or modify request based on parsed components.
}
return $this->json([
'url' => $this->parser->parseUrl($rawUrl)->__toString(),
]);
Deprecated Symfony 3+:
composer.json:
"extra": {
"symfony": {
"allow-overload": true
}
}
Underlying Library Limitations:
php-domain-parser has known issues:
例子.测试) correctly.http:///, http://example.com:) may throw unexpected errors.filter_var($url, FILTER_VALIDATE_URL).Container Access:
$this->container->get()) in modern Symfony. Prefer dependency injection or the ContainerAware trait (deprecated in Symfony 4+).Performance:
$cacheKey = 'url_'.$urlString;
$parsedUrl = $cache->get($cacheKey) ?: $this->parser->parseUrl($urlString);
$url = $parser->parseUrl('http://user:pass@example.com:8080/path');
var_dump([
'scheme' => $url->getScheme(),
'user' => $url->getUser(),
'pass' => $url->getPass(),
'host' => $url->getHost(),
'port' => $url->getPort(),
'path' => $url->getPath(),
'query' => $url->getQuery(),
'fragment' => $url->getFragment(),
]);
null Values:
The parser may return null for missing components (e.g., getPort() returns null for default ports like 80 or 443).Custom Parsing Logic: Extend the parser by creating a decorator:
class CustomDomainParser implements DomainParserInterface {
private $decorated;
public function __construct(DomainParser $parser) {
$this->decorated = $parser;
}
public function parseUrl($url) {
$parsed = $this->decorated->parseUrl($url);
// Add custom logic (e.g., normalize hostnames).
return $parsed;
}
}
Register the decorator in services.yaml:
services:
App\Service\CustomDomainParser:
decorates: 'egyg33k.domainParser'
arguments: ['@egyg33k.domainParser']
Override Default Behavior:
The bundle uses Egyg33k\DomainParserBundle\Parser\DomainParser, which wraps jeremykendall/php-domain-parser. Replace the service definition to use a custom implementation:
services:
egyg33k.domainParser:
class: App\Parser\CustomDomainParser
arguments:
- '@service_id_if_needed'
Testing: Mock the parser in tests to avoid external dependencies:
$mockParser = $this->createMock(DomainParserInterface::class);
$mockParser->method('parseUrl')->willReturn($expectedUrlObject);
$this->container->set('egyg33k.domainParser', $mockParser);
How can I help you explore Laravel packages today?