Weave 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 PHP standard library inspired by hhvm/hsl, offering consistent, well-typed, async-ready APIs for collections, networking, I/O, cryptography, terminal UI, and type-safe validation—replacing fragile PHP primitives with predictable alternatives. Requires PHP 8.4+.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strong alignment with modern PHP architectures: PSL’s structured concurrency (fibers), immutable collections, and type-safe APIs align well with Laravel’s evolving async/await support (PHP 8.1+) and Laravel’s growing emphasis on performance and type safety (e.g., Laravel 11’s PHP 8.4+ requirements).
  • Replaces legacy PHP primitives: PSL’s Vec, Dict, Str, and Async components directly address Laravel’s reliance on raw arrays, str_* functions, and callback-based async patterns (e.g., queues, jobs). This reduces boilerplate and improves maintainability.
  • Complementary to Laravel’s ecosystem:
    • Async: PSL’s Async/Fiber integration could replace Laravel’s Illuminate\Bus or Laravel\Horizon for lightweight, structured concurrency (e.g., batch processing, real-time APIs). Unchanged in 6.3.0 — no async work landed, so this remains aspirational rather than de-risked.
    • Collections: PSL’s Vector/Map/Set could augment or replace Laravel Collections (Illuminate\Support\Collection) for stricter typing and functional operations.
    • Type system: 6.3.0 adds Type\numeric(), which fills a real gap for Laravel request validation — numeric strings from query params, form posts, and CSV imports keep their original type instead of being silently cast, and Stringable objects (e.g. Laravel’s Stringable, backed enums with string values, money/quantity value objects) coerce cleanly. This is the single most Laravel-relevant addition in the release.
    • Networking: PSL’s TCP/TLS/HTTP components could underpin Laravel’s HTTP client (Guzzle) or replace Symfony\Component\HttpClient for low-level control. 6.3.0 hardens HTTP\Client response parsing (see risk table), which strengthens the security case for egress paths but introduces a new exception surface.
  • Potential conflicts:
    • Laravel’s Service Container may clash with PSL’s immutable/functional design (e.g., dependency injection vs. pure functions).
    • ORM integration: PSL’s type safety could conflict with Eloquent’s dynamic properties or relationships unless explicitly adapted.

Integration Feasibility

  • High for greenfield projects: PSL’s design is modular, allowing selective adoption (e.g., start with Async or Type validation).
  • Challenging for legacy Laravel apps:
    • Stateful vs. immutable: Laravel’s ORM, sessions, and caching rely on mutable state, while PSL enforces immutability. Hybrid patterns (e.g., PSL for DTOs, Laravel for persistence) would be needed.
    • Async compatibility: Laravel’s queues/jobs use promises/callbacks, while PSL favors fibers. Bridging these (e.g., via Async\run) would require careful sequencing.
  • Tooling support: PSL’s Psalm/PHPStan plugins enable gradual adoption by surfacing type errors early, but Laravel’s built-in tools (e.g., php artisan make:model) may need updates. Note 6.3.0’s Dict\diff() PHPDoc correction (scalar|null|resource|Stringable) is type-only and runtime-neutral, but expect a small burst of new static-analysis findings on first upgrade if Dict\diff() is in use.
  • Upgrade cost 6.2.1 → 6.3.0: no declared breaking changes; constraint bump from ^6.2 to ^6.3 is low-effort. One behavioral change (HTTP ProtocolException) needs a compatibility check before bumping production HTTP egress.

Technical Risk

Risk Area Severity Mitigation Strategy
Breaking changes High Start with non-critical paths (e.g., DTO validation). 6.3.0 itself is additive; the real risk remains cross-minor API churn in Type/Async.
Async complexity High Isolate PSL Async to specific services (e.g., workers). Untouched by 6.3.0 — no new evidence to lower this.
HTTP client behavior change (6.3.0) Medium HTTP\Client now raises ProtocolException on invalid/unsupported Transfer-Encoding (including repeated fields) instead of falling back to Content-Length; conflicting Content-Length values are rejected in HTTP/1.1 and H2 (identical duplicates still accepted). Audit any PSL-based egress to third-party or internal proxies, add ProtocolException handling, and prefer chunked precedence explicitly. Security-positive (anti-smuggling/desync), but a new failure mode.
Type system friction Medium Use PSL’s Type for input validation only. Type\numeric() reduces custom regex/is_numeric glue, but it preserves input type — downstream code must not assume int/float. Standardize on explicit casts at boundaries.
Performance overhead Low Benchmark PSL vs. native PHP (e.g., Vec vs. array_map). Type\numeric() adds a coercion hop; negligible, but measure on hot request paths.
Vendor lock-in Low PSL’s MIT license and modularity reduce risk. 6.3.0 shows healthy external contribution (3 first-time contributors).

Key Questions

  1. Adoption scope:
    • Should PSL replace Laravel’s core collections/async, or supplement them (e.g., for APIs/DTOs)?
    • Which components (e.g., Async, Type, Vec) offer the highest ROI? 6.3.0 makes Type a clearer first win via Type\numeric().
  2. Async strategy:
    • How to integrate PSL fibers with Laravel’s queue system (e.g., Async\run wrapping job execution)?
    • Will PSL’s structured concurrency replace Laravel’s Illuminate\Bus or coexist? No 6.3.0 movement here — treat as unresolved.
  3. Type safety:
    • Should PSL’s types override Laravel’s scalar types (e.g., non_empty_string vs. string)?
    • Where do we adopt Type\numeric() first — query-string pagination and filters, money/quantity fields, or CSV/import pipelines — and what is our policy on type-preserving validation vs. eager casting?
    • How to handle Eloquent models with PSL’s immutable constraints?
  4. Performance:
    • What’s the overhead of PSL’s type checks vs. native PHP?
    • Can PSL’s TCP/HTTP components outperform Guzzle/Symfony HTTP clients enough to justify the stricter-parsing operational burden introduced in 6.3.0?
  5. Tooling:
    • How to integrate PSL’s Psalm/PHPStan plugins with Laravel’s built-in tools?
    • Will mago or phpstan-extension replace Laravel’s IDE helpers?

Integration Approach

Stack Fit

  • Best for:
    • API layers: PSL’s Async/HTTP/Type for request validation and concurrent processing. Type\numeric() (6.3.0) is directly usable for pagination, sort indices, price/quantity params, and webhook numeric fields.
    • Background jobs: Replace Laravel queues with PSL fibers for lightweight, structured concurrency.
    • DTOs/validation: PSL’s Type for input validation (e.g., API payloads, form data).
    • Data pipelines: PSL’s Vec/Dict for functional transformations (e.g., ETL, reporting).
    • Egress/HTTP hardening: PSL HTTP\Client for outbound calls where strict response framing (6.3.0) is a security requirement.
  • Poor fit for:
    • ORM/persistence: PSL’s immutability conflicts with Eloquent’s dynamic properties.
    • Stateful services: Laravel’s sessions, caching, or real-time event systems may need wrappers.
    • Legacy callbacks: PSL’s fiber-based async won’t interop with Closure-based Laravel events.

Migration Path

  1. Phase 1: Validation and DTOs (Low Risk) — expanded by 6.3.0

    • Replace Laravel’s manual validation with PSL’s Type (e.g., API request DTOs).
    • Example:
      use Psl\Type;
      
      $userType = Type\shape([
          'name' => Type\non_empty_string(),
          'email' => Type\email_address(),
          'balance' => Type\numeric(), // new in 6.3.0 — '1.23' stays a string
      ]);
      $validated = $userType->coerce(request()->all());
      
    • New in 6.3.0: Type\numeric() accepts ints, floats, numeric strings, and Stringable objects whose string value is numeric, preserving the input type. Use it to retire ad-hoc is_numeric() checks; pair with explicit casting at the domain boundary so "numeric string stays string" is not a latent bug.
    • Tools: Use PSL’s Psalm plugin to catch type errors early.
  2. Phase 2: Collections (Medium Risk)

    • Replace Illuminate\Support\Collection with PSL’s Vec/Dict for functional operations.
    • Example:
      use Psl\Vec;
      
      $users = Vec\map($users, fn($user) => $user->name);
      
    • Challenge: Laravel’s Collection macros may need PSL equivalents. If Dict\diff() is used, re-run static analysis after upgrading — 6.3.0 narrowed the PHPDoc value bound to scalar|null|resource|Stringable (runtime unchanged).
  3. Phase 3: Async/Concurrency (High Risk)

    • Replace Laravel queues with PSL fibers for CPU-bound tasks.
    • Example:
      use Psl\Async;
      
      Async\main(static function() {
          $result = Async\concurrently([
              fn() => processOrder(1),
              fn() => sendNotification(2),
          ]);
      });
      
    • Challenge: Integrate with Laravel’s Illuminate\Bus or Laravel\Horizon. No change in 6.3.0 — sequencing and risk posture hold.
  4. Phase 4: Networking (High Risk)

    • Replace Guzzle/Symfony HTTP clients with PSL’s HTTP/TCP for custom protocols.
    • Example:
      use Psl\HTTP;
      
      $response = HTTP\request('GET', 'https://api.example.com');
      
    • Challenge: PSL’s low-level API may require wrappers for Laravel’s HTTP conventions.
    • New in 6.3.0: HTTP\Client validates every Transfer-Encoding response field (including repeated ones). Invalid or unsupported transfer codings now raise ProtocolException rather than falling back to Content-Length; valid chunked responses still win over Content-Length. Conflicting Content-Length fields are rejected in HTTP/1.1 and H2, while identical duplicates are accepted.
      • Action: wrap all PSL HTTP calls in a single adapter that maps ProtocolException into your retry/circuit-breaker policy, and alert on it — it likely signals a broken intermediary (misconfigured proxy, CDN, or worse, a desync attempt).

Compatibility

Laravel Component PSL Equivalent Compatibility Notes
Illuminate\Support\Collection Psl\Vec, Psl\Dict Functional APIs overlap; macros may need migration. Dict\diff() PHPDoc re-typed in 6.3.0.
Illuminate\Bus Psl\Async Fibers vs. queues; may need adapter layer. Unchanged in 6.3.0.
Guzzle/Symfony HTTP Psl\HTTP PSL is lower-level; middleware support needed. 6.3.0 strict framing → handle ProtocolException.
Laravel Validator Psl\Type (incl. numeric()) Complements rather than replaces; keep Laravel rules for user-facing messages, use PSL for DTO coercion.
Eloquent Models PSL Type (DTOs) Immutability conflicts; use PSL for validation only.
Blade Templates PSL Str Limited impact; use for string manipulation.

Sequencing

  1. Start with non-critical paths:
    • API validation (Type), now including Type\numeric() for numeric query/form/import fields.
    • Functional data transformations (Vec/Dict).
  2. Isolate async changes:
    • Use PSL fibers for new background services (e.g., workers).
    • Gradually migrate from queues to fibers.
  3. Avoid ORM conflicts:
    • Keep Eloquent models separate; use PSL for DTOs/input validation.
  4. Leverage tooling:
    • Enable PSL’s Psalm/PHPStan plugins early to catch issues.
    • Use mago for enhanced type inference during migration; re-baseline after the 6.3.0 Dict\diff() PHPDoc change.
  5. Pin and stage the 6.3.0 bump:
    • Ship the upgrade behind the existing test suite first; gate Phase 4 HTTP egress on ProtocolException handling landing beforehand.

Operational Impact

Maintenance

  • Pros:
    • Reduced boilerplate: PSL’s functional collections (Vec/Dict) eliminate manual array operations; Type\numeric() retires hand-rolled numeric guards.
    • Type safety: Catches bugs at compile time (e.g., invalid API inputs).
    • Consistent APIs: PSL’s standardized interfaces reduce context-switching.
    • Steady release cadence: 6.2.1 → 6.3.0 in a minor bump with no declared breaks keeps upgrade overhead low.
  • Cons:
    • Learning curve: Team must adopt functional programming patterns (e.g., immutability, pure functions), plus the type-preserving semantics of numeric().
    • Tooling dependency: Relies on Psalm/PHPStan for full benefits; may slow down CI, and PHPDoc-only changes (6.3.0 Dict\diff()) can shift analysis output without runtime change.
    • Debugging: Fibers/async code can be harder to debug than traditional callbacks.

Support

  • Pros:
    • Self-documenting types: Type\shape()/Type\numeric() express intent better than scattered validation rules, reducing support handoffs between API and domain teams.
    • Better docs surface (6.3.0): pre-rendered static doc pages, section permalinks, and a working custom domain make it cheaper to point engineers at canonical guidance during incidents and onboarding.
    • Healthy community: three first-time contributors in this release is a positive signal for long-term maintainability and issue responsiveness.
  • Cons:
    • Thin Laravel-specific guidance: upstream docs cover PSL, not Laravel idioms; internal runbooks are needed for container/Eloquent bridging.
    • ProtocolException is unfamiliar territory: support staff will need a documented triage path, since this is a protocol-level failure, not a typical timeout or 5xx.
    • Upstream is a small maintainer core: bus-factor risk persists despite new contributors.

Scaling

  • Pros:
    • Concurrency headroom: fibers remain the main long-term lever for I/O-bound throughput without proportional worker/container growth.
    • Predictable memory profiles: immutable Vec/Dict avoid surprise mutation and make capacity planning on data pipelines more predictable.
  • Cons:
    • Async scaling unproven for us: no 6.3.0 movement on Async, so the queue-vs-fiber capacity model is still an open, unbudgeted question.
    • Strict HTTP parsing at scale: under high egress volume, a misbehaving upstream or proxy will now produce ProtocolException bursts rather than silent Content-Length fallbacks — good for correctness, but it needs retry/backoff and alerting thresholds sized before rollout.
    • Static analysis cost: larger codebases will see CI time grow as PSL plugins are enabled repo-wide; scope them per-directory during migration.

Failure Modes

  • ProtocolException from HTTP\Client (6.3.0) — invalid/unsupported Transfer-Encoding, repeated transfer-coding fields, or conflicting Content-Length (HTTP/1.1 and H2; identical duplicates accepted). Presents as hard failures on previously "working" calls. Detect via exception type, alert on rate, and distinguish upstream breakage from active tampering.
  • Silent type drift with Type\numeric() — assertions succeed but the value keeps its original type ('1.23' stays a string). Downstream arithmetic or strict comparisons can fail or behave subtly differently. Mitigate with explicit casts at domain boundaries and static analysis.
  • Static-analysis regressions after PHPDoc changes — Dict\diff()'s narrowed value bound can surface new errors on upgrade despite identical runtime behavior. Pre-empt with a CI baseline diff.
  • Async deadlocks/starvation — fiber-based concurrency inside long-running Laravel workers can stall if blocking I/O is mixed in; isolate PSL async to dedicated services.
  • Immutability friction with Eloquent — attempting to treat models as PSL values leads to confusing partial-update bugs; keep a hard boundary at the DTO layer.
  • Container/DI confusion — pure PSL functions don't resolve from Laravel's container; misconfiguration shows up as "works in tests, fails in queue workers" inconsistencies.

Ramp-up

  • Low-friction entry: Phase 1 (Type) remains the right first step and is now more attractive thanks to Type\numeric(); a single DTO or form request is enough to demonstrate value.
  • Estimated effort: validation/DTO adoption ~1–2 sprints for a small team; collections migration ~2–3 sprints including macro parity; async and networking are multi-quarter, roadmap-gated efforts.
  • Onboarding assets to build: internal examples for Type\shape() + numeric(), a PSL HTTP adapter with ProtocolException handling, and a short functional-PHP primer for engineers raised on Eloquent/Collections.
  • Documentation lift: 6.3.0's static docs site and section permalinks make self-serve learning easier, but Laravel-specific bridging docs remain an internal responsibility.
  • Recommended 6.3.0 posture: treat as a low-risk, value-additive minor — adopt Type\numeric() in Phase 1 immediately, audit PSL HTTP egress before the version bump, and re-run static analysis to absorb the Dict\diff() PHPDoc change. No changes to the async risk posture or sequencing.
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.
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo