Download the PHP package jeremykendall/php-domain-parser without Composer
On this page you can find all versions of the php package jeremykendall/php-domain-parser. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download jeremykendall/php-domain-parser
More information about jeremykendall/php-domain-parser
Files in jeremykendall/php-domain-parser
Package php-domain-parser
Short Description Public Suffix List and IANA Root Zone Database based Domain parsing implemented in PHP.
License MIT
Homepage https://github.com/jeremykendall/php-domain-parser
Rated 5.00 based on 1 reviews
Informations about the package php-domain-parser
PHP Domain Parser
PHP Domain Parser is a resource based domain parser implemented in PHP.
Motivation
While there are plenty of excellent URL parsers and builders available, there are very few projects that can accurately parse a domain into its component subdomain, registrable domain, second level domain and public suffix parts.
Consider the domain www.pref.okinawa.jp. In this domain, the
public suffix portion is okinawa.jp, the registrable domain is
pref.okinawa.jp, the subdomain is www and
the second level domain is pref.
You can't regex that.
PHP Domain Parser is compliant around:
- accurate Public Suffix List based parsing.
- accurate IANA Top Level Domain List parsing.
Installation
Composer
composer require jeremykendall/php-domain-parser:^6.0
System Requirements
You need:
- PHP >= 7.4 but the latest stable version of PHP is recommended
- the
intl
extension - a copy of the Public Suffix List data and/or a copy of the IANA Top Level Domain List. Please refer to the Managing external data source section for more information when using this package in production.
Usage
[!WARNING] If you are upgrading from version 5 please check the upgrading guide for known issues.
Resolving Domains
This library can resolve a domain against:
In both cases this is done using the resolve
method implemented on the resource
instance. The method returns a Pdp\ResolvedDomain
object which represents the
result of that process.
For the Public Suffix List you need to use the
Pdp\Rules
class as shown below:
// display
// uk
// co
// bbc
// www
$publicSuffixDomain = $result->suffix()->domain();
$publicSuffixDomain->labels(); // returns ['uk', 'co']
You can also add or remove labels according to their key index using the following methods:
<?php
use Pdp\Domain;
use Pdp\Rules;
/** @var Rules $publicSuffixList */
$domain = $publicSuffixList->resolve(Domain::from2008('www.ExAmpLE.cOM'))->domain();
$newDomain = $domain
->withLabel(1, 'com') //replace 'example' by 'com'
->withoutLabel(0, -1) //remove the first and last labels
->append('www')
->prepend('docs.example');
echo $domain->toString(); //display 'www.example.com'
echo $newDomain->toString(); //display 'docs.example.com.www'
$newDomain->clear()->labels(); //return []
echo $domain->slice(2)->toString(); //display 'www'
[!WARNING] Because of its definition, a domain name can be
null
or a string.
To distinguish this possibility the object exposes two (2) formatting methods
Domain::value
which can be null
or a string
and Domain::toString
which
will always cast the domain value to a string.
use Pdp\Domain;
$nullDomain = Domain::fromIDNA2008(null);
$nullDomain->value(); // returns null;
$nullDomain->toString(); // returns '';
$emptyDomain = Domain::fromIDNA2008('');
$emptyDomain->value(); // returns '';
$emptyDomain->toString(); // returns '';
ASCII and Unicode formats.
Domain names originally only supported ASCII characters. Nowadays,
they can also be presented under a UNICODE representation. The conversion
between both formats is done using the compliant implementation of
UTS#46, otherwise known as Unicode
IDNA Compatibility Processing. Domain objects expose a toAscii
and a
toUnicode
methods which returns a new instance in the converted format.
<?php
use Pdp\Rules;
/** @var Rules $publicSuffixList */
$unicodeDomain = $publicSuffixList->resolve('bébé.be')->domain();
echo $unicodeDomain->toString(); // returns 'bébé.be'
$asciiDomain = $publicSuffixList->resolve('xn--bb-bjab.be')->domain();
echo $asciiDomain->toString(); // returns 'xn--bb-bjab.be'
$asciiDomain->toUnicode()->toString() === $unicodeDomain->toString(); //returns true
$unicodeDomain->toAscii()->toString() === $asciiDomain->toString(); //returns true
By default, the library uses IDNA2008 algorithm to convert domain name between both formats. It is still possible to use the legacy conversion algorithm known as IDNA2003.
Since direct conversion between both algorithms is not possible you need
to explicitly specific on construction which algorithm you will use
when creating a new domain instance via the Pdp\Domain
object. This
is done via two (2) named constructors:
Pdp\Domain::fromIDNA2008
Pdp\Domain::fromIDNA2003
At any given moment the Pdp\Domain
instance can tell you whether it is in
ASCII
mode or not.
[!WARNING] Once instantiated there's no way to tell which algorithm is used to convert the object from ascii to unicode and vice-versa
use Pdp\Domain;
$domain = Domain::fromIDNA2008('faß.de');
echo $domain->value(); // display 'faß.de'
$domain->isAscii(); // return false
$asciiDomain = $domain->toAscii();
echo $asciiDomain->value(); // display 'xn--fa-hia.de'
$asciiDomain->isAscii(); // returns true
$domain = Domain::fromIDNA2003('faß.de');
echo $domain->value(); // display 'fass.de'
$domain->isAscii(); // returns true
$asciiDomain = $domain->toAscii();
echo $asciiDomain->value(); // display 'fass.de'
$asciiDomain->isAscii(); // returns true
[!TIP] Always favor submitting a
Pdp\Domain
object for resolution rather that a string or an object that can be cast to a string to avoid unexpected format conversion errors/results. By default, and with lack of information conversion is done using IDNA 2008 rules.
Managing the package external resources
Depending on your application, the mechanism to store your resources may differ, nevertheless, the library comes bundle with a optional service which enables resolving domain name without the constant network overhead of continuously downloading the remote databases.
The interfaces and classes defined under the Pdp\Storage
namespace enable
integrating a resource managing system and provide an implementation example
using PHP-FIG PSR interfaces.
Using PHP-FIG interfaces
The Pdp\Storage\PsrStorageFactory
enables returning storage instances that
retrieve, convert and cache the Public Suffix List and the IANA Top Level
Domain List using standard interfaces published by the PHP-FIG.
To work as intended, the Pdp\Storage\PsrStorageFactory
constructor requires:
- a PSR-16 Simple Cache implementing library.
- a PSR-17 HTTP Factory implementing library.
- a PSR-18 HTTP Client implementing library.
When creating a new storage instance you will require:
- a
$cachePrefix
argument to optionally add a prefix to your cache index, default to the empty string; - a
$ttl
argument if you need to set the default$ttl
, default tonull
to use the underlying caching default TTL;
The $ttl
argument can be:
- an
int
representing time in second (see PSR-16); - a
DateInterval
object (see PSR-16); - a
DateTimeInterface
object representing the date and time when the item will expire;
The package does not provide any implementation of such interfaces as you can find robust and battle tested implementations on packagist.
Refreshing the resource using the provided factories
[!NOTE] THIS IS THE RECOMMENDED WAY OF USING THE LIBRARY
For the purpose of this example we will use our PSR powered solution with:
- Guzzle HTTP Client as our PSR-18 HTTP client;
- Guzzle PSR-7 package which provide factories to create a PSR-7 objects using PSR-17 interfaces;
- Symfony Cache Component as our PSR-16 cache implementation provider;
We will cache both external sources for 24 hours in a PostgreSQL database.
You are free to use other libraries/solutions/settings as long as they implement the required PSR interfaces.
<?php
use GuzzleHttp\Psr7\Request;
use Pdp\Storage\PsrStorageFactory;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\Cache\Psr16Cache;
$pdo = new PDO(
'pgsql:host=localhost;port:5432;dbname=testdb',
'user',
'password',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$cache = new Psr16Cache(new PdoAdapter($pdo, 'pdp', 43200));
$client = new GuzzleHttp\Client();
$requestFactory = new class implements RequestFactoryInterface {
public function createRequest(string $method, $uri): RequestInterface
{
return new Request($method, $uri);
}
};
$cachePrefix = 'pdp_';
$cacheTtl = new DateInterval('P1D');
$factory = new PsrStorageFactory($cache, $client, $requestFactory);
$pslStorage = $factory->createPublicSuffixListStorage($cachePrefix, $cacheTtl);
$rzdStorage = $factory->createTopLevelDomainListStorage($cachePrefix, $cacheTtl);
// if you need to force refreshing the rules
// before calling them (to use in a refresh script)
// uncomment this part or adapt it to you script logic
// $pslStorage->delete(PsrStorageFactory::PUBLIC_SUFFIX_LIST_URI);
$publicSuffixList = $pslStorage->get(PsrStorageFactory::PUBLIC_SUFFIX_LIST_URI);
// if you need to force refreshing the rules
// before calling them (to use in a refresh script)
// uncomment this part or adapt it to you script logic
// $rzdStorage->delete(PsrStorageFactory::TOP_LEVEL_DOMAIN_LIST_URI);
$topLevelDomains = $rzdStorage->get(PsrStorageFactory::TOP_LEVEL_DOMAIN_LIST_URI);
[!NOTE] Be sure to adapt the following code to your own application. The following code is an example given without warranty of it working out of the box.
[!WARNING] You should use your dependency injection container to avoid repeating this code in your application.
Automatic Updates
It is important to always have an up to date Public Suffix List and Top Level
Domain List.
This library no longer provide an out of the box script to do so as implementing
such a job heavily depends on your application setup.
You can use the above example script as a starting point to implement such a job.
Changelog
Please see CHANGELOG for more information about what has been changed since version 5.0.0 was released.
Contributing
Contributions are welcome and will be fully credited. Please see CONTRIBUTING for details.
Testing
pdp-domain-parser
has:
- a PHPUnit test suite
- a code analysis compliance test suite using PHPStan.
- a coding style compliance test suite using PHP CS Fixer.
To run the tests, run the following command from the project folder.
Security
If you discover any security related issues, please email [email protected] instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
Attribution
Portions of the Pdp\Rules
class are derivative works of the PHP
registered-domain-libs.
I've included a copy of the Apache Software Foundation License 2.0 in this project.
All versions of php-domain-parser with dependencies
ext-filter Version *
ext-intl Version *
ext-json Version *