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

Option Laravel Package

prewk/option

Lightweight Option type for PHP providing Some/None to avoid nulls. Adds map/flatMap/filter, unwrap with defaults, and safe chaining inspired by functional programming. Handy for Laravel and general PHP codebases where nullable values cause bugs.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Null Safety Paradigm: The Option type enforces explicit handling of absence, aligning with Rust-inspired functional patterns. This is a strong fit for Laravel applications where null checks are pervasive (e.g., API request handling, Eloquent queries, or middleware). The package’s design mitigates "null hell" by replacing implicit null with explicit Some/None variants, reducing runtime errors and improving code clarity.
  • Functional Composition: The map, filter, and flatMap methods enable declarative pipelines, which are particularly useful in Laravel’s request/response cycle (e.g., chaining validations or transformations). This complements Laravel’s existing functional tools (e.g., Collection methods) and reduces nested if-else or isset() logic.
  • Interoperability: The package integrates seamlessly with Laravel’s ecosystem:
    • Eloquent: Can wrap query results (e.g., User::find($id)->toOption()).
    • API Layer: Enables Option-returning controllers (e.g., Option<JsonResource>).
    • Dependency Injection: Works with Laravel’s service container for optional dependencies.
  • Type Safety: Leverages PHP 8.1+ features (e.g., union types, attributes) to future-proof the codebase. When paired with static analyzers like Psalm, it can catch type-related bugs early.
  • Trade-offs:
    • Verbosity: Methods like match() or unwrapOr() may introduce boilerplate compared to native PHP syntax (e.g., ?: or null coalescing).
    • Learning Curve: Teams unfamiliar with Rust/functional programming may resist the syntax (e.g., $option->map(fn($x) => ...)).
    • Overhead: Minimal runtime overhead, but static analysis tools must be configured to recognize Option types.

Integration Feasibility

  • Laravel Compatibility:
    • PHP 8.1+: Required; Laravel 9+ (PHP 8.0+) or 10+ (PHP 8.1+) are compatible. No framework conflicts exist, as the package is stateless and pure PHP.
    • Eloquent Synergy: Can be adapted to wrap Eloquent models/collections (e.g., Option::Some($user)). Custom toOption() methods can be added to Eloquent query builders.
    • API Layer: Simplifies controller logic by replacing return null with return Option::None and using match() for HTTP responses.
  • Dependency Risks:
    • prewk/result: Hard dependency. Assess whether Result is needed (e.g., for error handling) or if Option alone suffices. If Result is unnecessary, consider forking the package to remove it.
    • No Laravel-Specific Extensions: Requires manual adaptation (e.g., converting Laravel collections to Option or creating helper methods for common use cases).
  • Tooling Support:
    • Static Analysis: Psalm/PHPStan can leverage Option types if configured to recognize them (e.g., via custom type mappings).
    • IDE Support: Limited out-of-the-box; may require custom PHPDoc annotations for autocompletion.

Technical Risk

Risk Area Severity Mitigation Strategy
Breaking Changes Medium Test thoroughly with PHP 8.1–8.3; monitor updates to prewk/result.
Performance Overhead Low Benchmark critical paths; Option is a thin wrapper with negligible overhead.
Adoption Resistance High Pilot in a single module first; provide training and migration guides.
Type System Gaps Medium Use PHP 8.1 attributes (e.g., #[\ReturnTypeWillChange]) for gradual adoption.
Debugging Complexity Medium Add custom __toString() methods for Option in development.
Tooling Limitations Medium Configure Psalm/PHPStan to recognize Option types; create custom IDE plugins if needed.

Key Questions

  1. Adoption Scope:
    • Will Option replace all null returns in the codebase, or only specific domains (e.g., API layer, Eloquent queries)?
  2. Team Readiness:
    • Does the team have experience with functional programming or Rust-inspired patterns? If not, what training or documentation is needed?
  3. Tooling Support:
    • Can static analyzers (Psalm, PHPStan) be configured to recognize Option types for better error detection?
  4. Alternatives:
    • Compare with:
      • Custom Nullable trait or interface.
      • Laravel’s built-in Collection methods (e.g., first() + manual checks).
      • Third-party packages like Nette\Utils\Callback.
  5. Testing Impact:
    • How will existing unit tests (e.g., PHPUnit) need to adapt to expect Option types (e.g., mocking Some/None)?
  6. Long-Term Maintenance:
    • Who will maintain custom integrations (e.g., Eloquent toOption() methods) if the package evolves?
  7. Dependency Management:
    • Is prewk/result justified, or can the package be forked to remove it if unnecessary?

Integration Approach

Stack Fit

  • PHP 8.1+: Mandatory for full feature support (e.g., union types, attributes). Laravel 9+ (PHP 8.0+) may require polyfills or gradual migration.
  • Laravel Ecosystem:
    • Controllers: Replace return null with return Option::None and use match() for HTTP responses.
    • Services: Use Option in method signatures (e.g., findUser(): Option<User>) and leverage map/filter for functional pipelines.
    • Eloquent: Create a toOption() method for query results:
      $user = User::find(1)->toOption(); // Option::Some($user) or Option::None
      
    • API Resources: Wrap responses (e.g., Option<JsonResource>) for consistent error handling.
    • Middleware: Use Option to explicitly handle missing data (e.g., Option::fromRequest($request->input('token'))).
  • Third-Party Libraries:
    • Symfony Components: Works with Symfony\Component\OptionsResolver for configuration.
    • Doctrine: Use with Option in DTOs or repository methods (e.g., Option<User>).

Migration Path

  1. Phase 1: Proof of Concept (1–2 weeks)

    • Isolate a high-impact, low-complexity module (e.g., user authentication or API endpoints).
    • Refactor to use Option for nullable values (e.g., replace ?User with Option<User>).
    • Example:
      // Before
      public function findUser(?int $id): ?User { ... }
      
      // After
      public function findUser(?int $id): Option { ... }
      
    • Add helper methods (e.g., toOption() for Eloquent) and test thoroughly.
  2. Phase 2: Core Services (2–4 weeks)

    • Refactor services with high null complexity (e.g., payment processing, caching).
    • Replace isset($var) with Option::isSome($var) and null coalescing with getOrElse().
    • Example:
      // Before
      $name = $user->profile->name ?? 'Anonymous';
      
      // After
      $name = $user->profile()
          ->map(fn($profile) => $profile->name)
          ->getOrElse('Anonymous');
      
  3. Phase 3: API Layer (3–6 weeks)

    • Standardize controller returns (e.g., Option<JsonResource>).
    • Use middleware to convert Option to HTTP responses:
      return match ($user) {
          Option::Some($user) => new UserResource($user),
          Option::None => response()->json(['error' => 'Not found'], 404),
      };
      
    • Deprecate legacy null-returning endpoints via Laravel’s API resources or middleware.
  4. Phase 4: Full Adoption (Ongoing)

    • Enforce Option in new features and gradually refactor legacy code.
    • Use PHP 8.1 attributes (e.g., #[\ReturnTypeWillChange]) to mark deprecated null-returning methods.
    • Train the team on functional patterns (e.g., map/filter chaining).

Compatibility

  • Backward Compatibility:
    • Breaking: Existing null-returning code will fail if not updated. Mitigate with adapter methods:
      Option::fromNullable($var); // Converts ?T to Option<T>
      $var = $option->unwrapOr(null); // Falls back to null
      
    • **Partial Adoption
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor