azjezz/psl
PSL is a modern PHP standard library (PHP 8.4+) inspired by HHVM/HSL. It provides consistent, well-typed APIs for async, collections, networking, I/O, crypto, terminal UI, and data validation—safer, predictable alternatives to PHP’s built-ins.
Installation: Add via Composer:
composer require php-standard-library/php-standard-library
Requires PHP 8.4+.
First Use Case: Validate input data with Type combinators:
use Psl\Type;
$userType = Type\shape([
'name' => Type\non_empty_string(),
'age' => Type\positive_int(),
]);
$validated = $userType->coerce($_POST['user']);
Where to Look First:
Psl\Type for data validation/coercion.Psl\Async for structured concurrency (replaces Promises/callbacks).Psl\Vec, Psl\Dict for functional array operations.$schema = Type\shape([
'id' => Type\uuid(),
'roles' => Type\vec(Type\string()),
]);
$data = $schema->coerce($rawInput); // Throws on failure
Validator for complex schemas):
use Psl\Type;
$requestType = Type\shape([
'email' => Type\email_address(),
'terms' => Type\bool(),
]);
$validated = $requestType->coerce($request->all());
Async\main(static fn() => Async\concurrently([
fn() => Http\get('api/users'),
fn() => Cache\get('config'),
]));
Bus/Queue for async pipelines:
Async\run(fn() => User::find($id)->processOrder());
$users = Vec\filter($users, fn($u) => $u['active']);
$names = Vec\map($users, fn($u) => $u['name']);
$activeUsers = Vec\filter($usersCollection, fn($user) => $user->active);
$server = TCP\listen('0.0.0.0', 8080);
while (true) {
$conn = $server->accept();
Async\run(fn() => handleConnection($conn));
}
Http facade for raw TCP/UDP.Fibers vs. Threads:
Async\main() uses fibers (not threads). Avoid blocking calls (e.g., sleep()).Async\sleep() instead.Type Coercion:
coerce() throws on failure. Use validate() for silent checks:
if (!$userType->validate($data)) {
// Handle error
}
Immutable Collections:
Vec\map() return new collections. Avoid mutating originals.try-catch:
try {
$result = Async\run(fn() => riskyOperation());
} catch (Async\Exception\Error $e) {
report($e);
}
Psl\Type\type() to inspect:
$type = Type\type($data); // Returns Type\TypeInterface
Type\register('custom_type', fn($value) => /* logic */);
Async\onError(fn($error) => Log::error($error));
// app/Providers/PslServiceProvider.php
public function register()
{
$this->app->singleton(Async\Scheduler::class, fn() => new Async\FiberScheduler());
}
Async\run() over then() for CPU-bound tasks.Vec\map() is faster than array_map() for large datasets.# psalm-plugin.yaml
plugins:
- PslPlugin
How can I help you explore Laravel packages today?