Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Psl Laravel Package

azjezz/psl

PSL is a modern, well-typed standard library for PHP 8.4+, inspired by HHVM’s HSL. It offers safer, predictable APIs for async, collections, networking, I/O, crypto, terminal UI, and robust data validation—replacing brittle built-ins with consistent alternatives.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation: Add via Composer:

    composer require php-standard-library/php-standard-library
    

    Requires PHP 8.4+.

  2. First Use Case: Validate input data with Type\shape():

    use Psl\Type;
    
    $userType = Type\shape([
        'name' => Type\non_empty_string(),
        'age'  => Type\positive_int(),
    ]);
    
    $validated = $userType->coerce($_POST['user']);
    
  3. Where to Look First:

    • Documentation (official guide)
    • src/Psl/ (core components)
    • examples/ (practical use cases in the repo)

Implementation Patterns

Core Workflows

1. Data Validation & Coercion

  • Pattern: Use Type\shape() for nested validation with composable types.
    $orderType = Type\shape([
        'items' => Type\vec(Type\shape([
            'id'    => Type\positive_int(),
            'price' => Type\positive_float(),
        ])),
        'total' => Type\positive_float(),
    ]);
    
  • Integration: Validate API payloads, form submissions, or config files.

2. Async Operations

  • Pattern: Structured concurrency with Async\concurrently().
    Async\main(static function() {
        [$user, $orders] = Async\concurrently([
            static fn() => UserRepository::fetch(1),
            static fn() => OrderRepository::fetchForUser(1),
        ]);
        return view('dashboard', ['user' => $user, 'orders' => $orders]);
    });
    
  • Integration: Replace Promises/callbacks in Laravel’s Job classes or Route handlers.

3. Functional Collections

  • Pattern: Replace array_map/array_filter with typed Vec/Dict:
    use Psl\Vec;
    use Psl\Str;
    
    $uppercaseNames = Vec\map($users, fn($user) => Str\uppercase($user['name']));
    
  • Integration: Use in Eloquent collections or service-layer transformations.

4. Networking

  • Pattern: Async TCP server in Laravel’s Artisan command:
    use Psl\Async;
    use Psl\TCP;
    
    Async\main(static function() {
        $server = TCP\listen('0.0.0.0', 3333);
        while (true) {
            $conn = $server->accept();
            Async\run(static fn() => handleConnection($conn))->ignore();
        }
    });
    
  • Integration: Build real-time APIs (e.g., WebSocket-like endpoints).

Laravel-Specific Patterns

1. Service Layer Validation

  • Pattern: Replace Laravel’s Validator with PSL’s Type in service methods:
    public function createUser(array $data): User {
        $userType = Type\shape([
            'name' => Type\non_empty_string(),
            'email' => Type\email_address(),
        ]);
        $validated = $userType->coerce($data);
        return User::create($validated);
    }
    

2. Job Queues with Structured Concurrency

  • Pattern: Run multiple jobs concurrently in a single Job:
    public function handle() {
        Async\main(static function() {
            [$job1, $job2] = Async\concurrently([
                static fn() => $this->dispatch(new ProcessPayment()),
                static fn() => $this->dispatch(new SendNotification()),
            ]);
            $job1->wait();
            $job2->wait();
        });
    }
    

3. API Response Transformation

  • Pattern: Use Vec/Dict to transform Eloquent collections:
    public function index() {
        $users = Vec\map(User::all(), fn($user) => [
            'id' => $user->id,
            'name' => Str\lowercase($user->name),
        ]);
        return response()->json($users);
    }
    

4. Dependency Injection

  • Pattern: Bind PSL components in Laravel’s ServiceProvider:
    $this->app->bind(GraphInterface::class, fn() => new DirectedGraph());
    

Gotchas and Tips

Pitfalls

  1. Async Context:

    • Gotcha: Async\main() must be the outermost function. Nesting it incorrectly causes silent failures.
    • Fix: Use Async\run() for nested async operations.
      Async\main(static function() {
          Async\run(static fn() => doAsyncWork())->ignore();
      });
      
  2. Type Coercion:

    • Gotcha: Type\coerce() throws on invalid data. Use Type\validate() for silent checks.
      if (!$userType->validate($data)) {
          return back()->withErrors(['data' => 'Invalid input']);
      }
      
  3. Immutable Collections:

    • Gotcha: Vec\map() returns a new collection. Avoid overwriting variables:
      // ❌ Bug-prone
      $users = Vec\map($users, fn($user) => [...]);
      
      // ✅ Safer
      $users = Vec\map($users, fn($user) => [...]);
      
  4. Fiber Compatibility:

    • Gotcha: PSL’s async uses fibers (PHP 8.1+). Avoid mixing with Swoole/ReactPHP without isolation.
    • Tip: Use Async\run() to bridge PSL async with other libraries.
  5. Performance:

    • Gotcha: Type\shape() validation has reflection overhead. Cache types for repeated use:
      private Type\Shape $userType;
      public function __construct() {
          $this->userType = Type\shape([...]);
      }
      

Debugging Tips

  1. Async Errors:

    • Use Async\run()->catch(fn($e) => error_log($e))->ignore() to log uncaught errors.
  2. Type Mismatches:

    • Enable PSL’s Psalm plugin for static analysis:
      composer require --dev php-standard-library/psalm-plugin
      
  3. Networking:

    • Test TCP/UDP connections locally with:
      Async\main(static fn() => TCP\connect('localhost', 8080)->ignore());
      

Extension Points

  1. Custom Types:

    • Extend Type\TypeInterface for domain-specific validation:
      class EmailType implements TypeInterface {
          public function coerce(mixed $value): string { ... }
      }
      
  2. Graph Algorithms:

    • Implement custom traversal logic by extending Graph\Traversal.
  3. Async Middleware:

    • Create PSL-compatible middleware for Laravel:
      public function handle($request, Closure $next) {
          return Async\run(static fn() => $next($request))->ignore();
      }
      
  4. Collection Macros:

    • Add custom methods to Vector/Map:
      Vector::macro('groupBy', fn($keyFn) => ...);
      

Config Quirks

  • Fiber Memory: PSL fibers retain state. Use Async\run() sparingly in loops to avoid leaks.
  • PHP 8.4+: Some features (e.g., Type\enum()) require PHP 8.4’s enums.
  • Autoloading: Ensure psl namespace is auto-loaded in composer.json.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport