Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
P

php-domain-parser

> 编程语言
Open source

Public Suffix List based domain parsing implemented in PHP

1.2K stars0 likes2 views
WebsiteGitHub

About

Public Suffix List based domain parsing implemented in PHP

PHP Domain Parser

PHP Domain Parser is a resource based domain parser implemented in PHP.

[![Build Status][ico-github-actions-build]][link-github-actions-build] [![Total Downloads][ico-packagist]][link-packagist] [![Latest Stable Version][ico-release]][link-release] [![Software License][ico-license]][link-license]

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 >= 8.1 but the latest stable version of PHP is recommended
  • 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.

Handling of an IDN host requires the presence of the intl extension or a polyfill for the intl IDN functions like the symfony/polyfill-intl-idn otherwise an exception will be thrown when attempting to validate or interact with such a host.

[!WARNING] When upgrading to version 6.4 you MUST refresh your local cache for the fix on private domain resolution to take effect.

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:

  • The Public Suffix List
  • The IANA Top Level Domain List

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:

php
resolve($domain);
echo $result->domain()->toString();            //display 'www.pref.okinawa.jp';
echo $result->subDomain()->toString();         //display 'www';
echo $result->secondLevelDomain()->toString(); //display 'pref';
echo $result->registrableDomain()->toString(); //display 'pref.okinawa.jp';
echo $result->suffix()->toString();            //display 'okinawa.jp';
$result->suffix()->isICANN();                  //return true;

For the IANA Top Level Domain List, the Pdp\TopLevelDomains class is use instead:

php
resolve($domain);
echo $result->domain()->toString();            //display 'www.pref.okinawa.jp';
echo $result->suffix()->toString();            //display 'jp';
echo $result->secondLevelDomain()->toString(); //display 'okinawa';
echo $result->registrableDomain()->toString(); //display 'okinawa.jp';
echo $result->subDomain()->toString();         //display 'www.pref';
echo $result->suffix()->isIANA();              //return true

In case of an error an exception which extends Pdp\CannotProcessHost is thrown.

The resolve method will always return a ResolvedDomain even if the domain syntax is invalid or if there is no match found in the resource data. To work around this limitation, the library exposes more strict methods, namely:

  • Rules::getCookieDomain
  • Rules::getICANNDomain
  • Rules::getPrivateDomain

for the Public Suffix List and the following method for the Top Level Domain List:

  • TopLevelDomains::getIANADomain

These methods resolve the domain against their respective data source using the same rules as the resolve method but will instead throw an exception if no valid effective TLD is found or if the submitted domain is invalid.

[!CAUTION] All these methods expect as their sole argument a Pdp\Host implementing object, but other types (ie: string, null and stringable objects) are supported with predefined conditions as explained in the remaining document.

php
getICANNDomain($domain);
// will throw because `.unknownTLD` is not part of the ICANN section

$result = $publicSuffixList->getCookieDomain($domain);
$result->suffix()->value();   // returns 'unknownTLD'
$result->suffix()->isKnown(); // returns false
// will not throw because the domain syntax is correct.

$publicSuffixList->getCookieDomain(Domain::fromIDNA2008('com'));
// will not throw because the domain syntax is invalid (ie: does not support public suffix)

$result = $publicSuffixList->resolve(Domain::fromIDNA2008('com'));
$result->suffix()->value();   // returns null
$result->suffix()->isKnown(); // returns false
// will not throw but its public suffix value equal to NULL

$topLevelDomains = TopLevelDomains::fromPath('/path/to/cache/public-suffix-list.dat');
$topLevelDomains->getIANADomain(Domain::fromIDNA2008('com'));
// will not throw because the domain syntax is invalid (ie: does not support public suffix)

To instantiate each domain resolver you can use the following named constructor:

  • fromString: instantiate the resolver from a inline string representing the data source;
  • fromPath: instantiate the resolver from a local path or online URL by relying on fopen;

If the instantiation does not work an exception will be thrown.

[!WARNING] You SHOULD never resolve domain name this way in production, without, at least, a caching mechanism to reduce external resource downloads. Using the Public Suffix List to determine what is a valid domain name and what isn't is dangerous, and MAY lead to errors because of new gTLDs being registered on a regular basis. If you are looking to know the validity of a Top Level Domain, you MUST use the IANA Top Level Domain List as the proper source for this information or alternatively the DNS. If you MUST use this library for any of the above purposes, you SHOULD consider integrating an updating mechanism into your software. For more information go to the Managing external data source section**

Resolved domain information.

Whichever methods chosen to resolve the domain on success, the package will return a Pdp\ResolvedDomain instance.

The Pdp\ResolvedDomain decorates the Pdp\Domain class resolved but also gives access as separate methods to the domain different components.

php
use Pdp\Domain;
use Pdp\TopLevelDomains;

$domain = Domain::fromIDNA2008('www.PreF.OkiNawA.jP');
/** @var TopLevelDomains $topLevelDomains */
$result = $topLevelDomains->resolve($domain);
echo $result->domain()->toString();            //display 'www.pref.okinawa.jp';
echo $result->suffix()->toString();            //display 'jp';
echo $result->secondLevelDomain()->toString(); //display 'okinawa';
echo $result->registrableDomain()->toString(); //display 'okinawa.jp';
echo $result->subDomain()->toString();         //display 'www.pref';
echo $result->suffix()->isIANA();              //return true

You can modify the returned Pdp\ResolvedDomain instance using the following methods:

php
resolve(Domain::fromIDNA2008('shop.example.com'));
$altResult = $result
    ->withSubDomain(Domain::fromIDNA2008('foo.bar'))
    ->withSecondLevelDomain(Domain::fromIDNA2008('test'))
    ->withSuffix(Domain::fromIDNA2008('example'));

echo $result->domain()->toString(); //display 'shop.example.com';
$result->suffix()->isKnown();       //return true;

echo $altResult->domain()->toString(); //display 'foo.bar.test.example';
$altResult->suffix()->isKnown();       //return false;

[!TIP] Always favor submitting a Pdp\Suffix object rather that any other supported type to avoid unexpected results. By default, if the input is not a Pdp\Suffix instance, the resulting public suffix will be labelled as being unknown. For more information go to the Public Suffix section

[!NOTE] Since version 6.4 Domain resolution is also adapted so that absolute domain can effectively be resolved. Prior to version 6.4 an exception was thrown.

Domain Suffix

The domain effective TLD is represented using the Pdp\Suffix. Depending on the data source the object exposes different information regarding its origin.

php
resolve(Domain::fromIDNA2008('example.github.io'))->suffix();

echo $suffix->domain()->toString(); //display 'github.io';
$suffix->isICANN();                 //will return false
$suffix->isPrivate();               //will return true
$suffix->isPublicSuffix();          //will return true
$suffix->isIANA();                  //will return false
$suffix->isKnown();                 //will return true

The public suffix state depends on its origin:

  • isKnown returns true if the value is present in the data resource.
  • isIANA returns true if the value is present in the IANA Top Level Domain List.
  • isPublicSuffix returns true if the value is present in the Public Suffix List.
  • isICANN returns true if the value is present in the Public Suffix List ICANN section.
  • isPrivate returns true if the value is present in the Public Suffix List private section.

The same information is used when Pdp\Suffix object is instantiate via its named constructors:

php
 resolve(Domain::from2008('www.bbc.co.uk'));
$domain = $result->domain();
echo $domain->toString(); // display 'www.bbc.co.uk'
count($domain);           // returns 4
$domain->labels();        // returns ['uk', 'co', 'bbc', 'www'];
$domain->label(-1);       // returns 'www'
$domain->label(0);        // returns 'uk'
foreach ($domain as $label) {
   echo $label, PHP_EOL;
}
// 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
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'

Starting with version 6.4 it is possible to specify and handle absolute domain with the following methods.

php
resolve(Domain::from2008('www.ExAmpLE.cOM'))->domain();
$newDomain = $domain->withRootLabel();

echo $domain->toString();    //display 'www.example.com'
echo $newDomain->toString(); //display 'www.example.com.www.'
$domain->isAbsolute();       //return false
$newDomain->isAbsolute()     //return true

$domain->value() === $newDomain->withoutRootLabel()->value();

[!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.

php
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 unde

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

PHP

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言