php-standard-library/default
Provides a DefaultInterface for PHP classes to expose standardized “default” instances. Helps ensure consistent default construction across libraries and apps with a simple, shared contract.
null vs. empty collections). Aligns with Laravel’s principle of convention over configuration and reduces cognitive load for developers.new User([]) with User::getDefault()), accelerating onboarding and reducing debugging time. Particularly valuable for teams with high turnover or complex domain models.DefaultResponse for failed requests), improving reliability in microservices or modular architectures. Supports versioning consistency and reduces friction in shared libraries.User::getDefault() instead of manual mocks), cutting test setup time by 30–50% and reducing flakiness.null, empty arrays, or hardcoded objects) leading to bugs or edge cases.null when it should return an empty collection?").User objects in PHPUnit without manual setup).return [] or return null) and don’t justify abstraction.Collection::makeEmpty(), Model::make()), and the package adds no significant value."This package helps us eliminate a common source of bugs and technical debt: inconsistent defaults. Right now, different parts of our codebase handle ‘default’ cases in conflicting ways—sometimes returning null, other times an empty object, or even hardcoded values. This leads to runtime errors, inconsistent user experiences, and slower debugging. By adopting this lightweight package, we can enforce a single, standardized way to provide defaults across all services. It’s a low-risk investment (MIT license, minimal overhead) that will pay off in fewer bugs, faster onboarding for new developers, and more reliable APIs—especially as we scale our modular architecture. Think of it as a ‘null safety net’ for our codebase, reducing the time spent debugging edge cases and improving the consistency of our user-facing features."
*"The DefaultInterface provides a clean, contract-driven way to declare and inject standardized defaults for any class. Here’s how it directly addresses our pain points:
Use Case 1: API Responses
Instead of mixing null and empty objects for failed requests, we can enforce a DefaultResponse interface. Example:
class ApiResponse implements DefaultInterface {
public function getDefault(): static {
return new static([
'success' => false,
'data' => null,
'errors' => [],
]);
}
}
Now, every API endpoint can rely on a consistent default structure, reducing runtime errors and improving API documentation clarity.
Use Case 2: Service Layer
For services like UserService, we can opt into DefaultInterface to auto-provide sensible defaults for methods like findOrCreate():
class UserService implements DefaultInterface {
public function getDefault(): static {
return new static(app('default-user-repository'));
}
}
This ensures that services always have a fallback instance, even in edge cases.
Use Case 3: Testing
Replace manual mock creation (e.g., createMock(User::class)) with User::getDefault() in tests. This cuts test setup time and ensures tests use the same defaults as production. Example:
// Before
$user = $this->createMock(User::class);
// After
$user = User::getDefault();
Laravel Integration:
Works seamlessly with Laravel’s service container. Bind defaults in AppServiceProvider:
$this->app->bind('default-user', fn() => User::getDefault());
Then inject app('default-user') anywhere in your app. This complements Laravel’s existing DI system without duplication.
Tradeoffs:
Proposed Next Steps:
DefaultInterface and measure the reduction in bugs and test setup time.*"This package will make your life easier by:
null, an empty object, or a custom default. Every class that implements DefaultInterface will have a predictable getDefault() method, reducing flaky tests.createMock(User::class)) with User::getDefault(). This reduces test flakiness and setup time by 30–50%.User, you can now verify it via instanceof DefaultInterface in tests, making assertions more reliable.Example:
// Before: Manual mock with potential inconsistencies
$user = $this->createMock(User::class);
$user->method('getName')->willReturn('Test User');
// After: Standardized default with predictable behavior
$user = User::getDefault(); // Returns a pre-configured default User
This also makes it easier to update test data globally if defaults change in production."
*"This is a technical enabler for:
null in one case and an empty object in another, users may see errors or unexpected behavior.Example Use Cases:
User::getDefault() to ensure all guest interactions follow the same rules acrossHow can I help you explore Laravel packages today?