- How do I install petrknap/optional in a Laravel project?
- Install it with Composer via composer require petrknap/optional. There is no service provider, facade, config file, or migration to publish, so installation is complete once the package is autoloaded. It is a framework-agnostic value object, so it works the same in Laravel as in any plain PHP project. Just import PetrKnap\Optional\Optional where you need it.
- Does petrknap/optional support Laravel 10, 11 and 12?
- The package has no Laravel coupling at all, so its compatibility depends only on the PHP version your application runs, not the Laravel release. It is expected to be compatible in principle with PHP 8+ and Laravel 9 through 12. Before adopting it, check the PHP constraint in the package's composer.json and confirm it matches your runtime. There is no Laravel integration surface that could break between framework versions.
- Is there a Laravel service provider or facade for Optional?
- No. petrknap/optional ships no service provider, no facade, no configuration and no Eloquent hooks, which is architecturally clean but also means there is nothing to register in your app. You simply use the Optional class or your own typed subclasses directly. Any Laravel-style sugar, such as container bindings or helpers, is something your team would have to write and own.
- How is Optional different from PHP 8 nullable types and the nullsafe operator?
- Nullable return types and the ?-> operator already let PHP express absence, and Laravel idioms such as nullable returns, Collection::filter and exceptions cover most null handling. Optional makes absence an explicit, first-class value that callers must check with isPresent() before calling get(), and it adds orElse() defaults and ifPresent() callbacks. Adopting it is therefore a stylistic choice about explicitness rather than filling a gap in the framework. The real question is whether that extra ceremony buys clearer contracts in the specific code paths where you use it.
- How do I create a strictly typed Optional like Optional<Money> or Optional<OrderId>?
- The package provides NonGenericOptional for fixed types such as bool or string, GenericOptional for generic structures such as arrays, and AbstractOptional for extendable factory optionals that act as a base class. You extend Optional, use the appropriate trait, and implement isSupported() to validate the wrapped value, then annotate the class with @extends Optional<YourType> for static analysis. This is the most credible reason to adopt the package: type-safe absence at domain boundaries. Keep these wrappers in your domain layer rather than spreading them through controllers and Eloquent relations.
- Does petrknap/optional support PHPStan and Psalm static analysis?
- The README advertises full static analysis support for the typed-wrapper traits through generics-style @extends annotations. However, the plugin surface, meaning PHPStan or Psalm extension registration, needs verification before you rely on it in CI. Do a short technical spike: build one typed wrapper and run your analyzer on a 200 to 500 line slice. Also pin the analyzer version, since generic annotation handling can shift between PHPStan and Psalm releases.
- Is petrknap/optional safe to use in production?
- Treat it as effectively self-maintained. It has zero stars, zero dependents and a single maintainer, which means no production battle-testing you can point to and no community support footprint. If you adopt it, vendor a tagged release, pin a commit hash, write a short internal ADR, and pre-agree a fork-and-vendor contingency. The default posture should be hold unless a bounded pilot shows a concrete, measurable win.
- What license does petrknap/optional use, and is LGPL-3.0 okay for a commercial Laravel app?
- The package is LGPL-3.0, which is a copyleft license and not a neutral choice. Copyleft is usually acceptable for libraries consumed purely through autoloading, but any organization distributing a packaged Laravel or SaaS binary, or modifying the library itself, should get legal sign-off first. Note that LGPL obligates you to publish modifications to the library, which matters if you fork it under a contingency plan. Make this review blocking before any pilot starts.
- How do I test code that uses Optional in Laravel with PHPUnit or Pest?
- There is nothing to mock or fake, because Optional is a plain value object with no framework dependencies. Assert directly on behavior: isPresent() for presence, get() for the contained value, orElse() for defaults and ifPresent() for callback side effects. Typed wrappers can be unit tested the same way, including their isSupported() validation. If you adopt the pattern, add these assertions to your existing feature or unit suites rather than creating a separate test strategy.
- Should I use Optional everywhere in my Laravel app, or are there alternatives?
- Do not retrofit existing controllers, Eloquent relations or service returns, because that is how you end up with a two-paradigm codebase. The recommended approach is a single bounded domain module, such as payments or pricing, where absence is business-meaningful, and Optional appears only at that module's public boundaries. The alternatives are already in your stack: PHP 8 nullable types, the ?-> operator, Collection::filter and exceptions. Run the pattern for one sprint, measure static-analysis coverage and bug delta, then decide to expand, hold or drop.