azjezz/psl
PSL (PHP Standard Library) offers a consistent, well-typed set of safer, async-ready APIs to replace PHP primitives. Covers async, collections, networking, I/O, cryptography, terminal UI, and type-safe data validation with predictable errors.
Installation:
composer require azjezz/psl:^6.2.1
The package provides a Public Suffix List (PSL) parser and validator, enabling domain parsing and validation (e.g., extracting example.com from sub.example.com.co.uk). Note: This release includes security fixes for the Psl\H2 component, which does not affect core PSL functionality unless you directly use Psl\H2\ServerConnection.
First Use Case:
Parse a domain to extract its registered domain (e.g., google.com from mail.google.com):
use Azjezz\Psl\Psl;
$psl = new Psl();
$domain = 'sub.example.co.uk';
$registeredDomain = $psl->parse($domain); // Returns 'example.co.uk'
Key Classes:
Psl: Core class for parsing/validating domains (unchanged).Psl\Exception\InvalidDomainException: Thrown for invalid domains (e.g., example..com).composer update (no breaking changes to core PSL logic).Where to Look First:
tests/ for usage examples (e.g., DomainParserTest.php).src/Psl.php for API reference.Psl\H2\ServerConnection, review the security advisory.Domain Parsing (Unchanged):
$psl = new Psl();
$result = $psl->parse('sub.domain.co.jp'); // Returns 'domain.co.jp'
.test).string (registered domain) or null for invalid domains.Validation (Unchanged):
try {
$psl->validate('invalid..domain.com'); // Throws InvalidDomainException
} catch (\Azjezz\Psl\Exception\InvalidDomainException $e) {
// Handle invalid domain
}
Integration with Laravel (Unchanged):
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'domain' => ['required', function ($attribute, $value, $fail) {
$psl = new Psl();
if (!$psl->validate($value)) {
$fail('The '.$attribute.' must be a valid domain.');
}
}]
]);
public function handle($request, Closure $next) {
$psl = new Psl();
if (!$psl->validate($request->domain)) {
abort(400, 'Invalid domain');
}
return $next($request);
}
Batch Processing (Unchanged):
$domains = ['example.com', 'sub.test', 'invalid..domain'];
$psl = new Psl();
$results = array_map([$psl, 'parse'], $domains);
// $results = ['example.com', 'test', null]
Custom PSL Updates (Unchanged):
$psl = new Psl('/path/to/custom/psl.txt');
If your application directly uses Psl\H2\ServerConnection (e.g., for custom HTTP/2 server logic), this release includes critical fixes:
DATA frames match declared content-length headers (RFC 9113 compliance).Psl\H2\Exception\StreamException on mismatches or overflows.waitForSendWindow() now flushes pending writes to prevent deadlocks.Example of Safe HTTP/2 Usage:
use Azjezz\Psl\H2\ServerConnection;
try {
$connection = new ServerConnection($socket);
$stream = $connection->acceptStream();
$headers = $stream->receiveHeaders(); // Validates content-length
$data = $stream->receiveData(); // Throws on size mismatch
} catch (\Azjezz\Psl\H2\Exception\StreamException $e) {
\Log::error("HTTP/2 stream error: {$e->getMessage()}");
$connection->closeStream($stream->id());
}
IDN Handling (Unchanged):
idn_to_ascii() for normalization:
$psl->parse(idn_to_ascii('例子.测试')); // Returns '测试'
Private TLDs (Unchanged):
.localhost).Performance (Unchanged):
Psl instance for high-throughput apps:
$psl = app()->singleton(Psl::class, fn() => new Psl());
HTTP/2 Security Risks (New):
Psl\H2\ServerConnection with untrusted client traffic.^6.2.1 and validate streams as shown above.Psl class) remains unchanged.Exception Handling (Unchanged):
InvalidDomainException for malformed domains (e.g., example..com).Verify PSL Updates (Unchanged):
$psl = new Psl();
echo $psl->getPslVersion(); // Check loaded PSL version.
HTTP/2 Stream Errors (New):
StreamException for debugging:
try {
$data = $stream->receiveData();
} catch (\Azjezz\Psl\H2\Exception\StreamException $e) {
\Log::debug("Stream {$stream->id()} failed: {$e->getMessage()}");
}
Test Edge Cases (Unchanged):
Custom PSL Rules (Unchanged):
Psl for blacklists or additional logic.HTTP/2 Custom Logic (New):
ServerConnection methods to handle custom stream validation:
class CustomH2Connection extends ServerConnection {
protected function validateHeaders(array $headers): void {
parent::validateHeaders($headers);
// Add custom header validation
}
}
Laravel Integration (Unchanged):
Psl to the container and use dependency injection.PSL File Management (Unchanged):
Security Note: If you do not use Psl\H2\ServerConnection, this update is a non-breaking change and requires no action. Only applications handling untrusted HTTP/2 traffic with the H2 component must upgrade.
How can I help you explore Laravel packages today?