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.
composer require php-standard-library/default
DefaultInterface to a class and define getDefault():
use PHPStandardLibrary\Default\DefaultInterface;
class User implements DefaultInterface
{
public function getDefault(): static
{
return new static([
'name' => 'Guest',
'email' => null,
]);
}
}
// Before
$user = new User(['name' => 'Guest']);
// After
$user = User::getDefault();
DefaultInterface.php for the contract.AppServiceProvider bindings and testing patterns.Service Layer Defaults:
Bind defaults in AppServiceProvider:
$this->app->bind('default-user', fn() => User::getDefault());
Use in controllers:
$user = app('default-user');
Repository Pattern:
Enforce DefaultInterface in RepositoryInterface:
interface RepositoryInterface {
public function getDefault(): static;
}
API Responses:
Standardize default Resource objects:
class UserResource implements DefaultInterface {
public function getDefault(): static {
return new static(['data' => null]);
}
}
Testing:
Replace mocks with getDefault():
// Before
$mockUser = Mockery::mock(User::class);
// After
$defaultUser = User::getDefault();
New Class Adoption:
DefaultInterface to the class.getDefault() with sensible defaults.Refactoring:
php artisan tinker to test getDefault():
php artisan tinker
>>> User::getDefault()
new Class() with Class::getDefault() in legacy code.Modular Applications:
trait HasDefaultConfig {
public function getDefault(): static {
return new static(config('app.defaults'));
}
}
class UserFacade extends \Illuminate\Support\Facades\Facade {
public static function default() {
return app('default-user');
}
}
config():
public function getDefault(): static {
return new static(config('app.default_user_attributes'));
}
$this->app->when(User::class)
->needs('$default')
->give(fn() => User::getDefault());
Eager Initialization:
getDefault() in boot() may load defaults too early.State Contamination:
public function getDefault(): static {
return new static(); // No shared state
}
Interface Bloat:
DefaultInterface to every class feels redundant.Testing Overhead:
getDefault().method_exists() checks for backward compatibility.Undefined Method Errors:
getDefault().php artisan ide-helper:generate to check interfaces.Default State Issues:
getDefault() returns invalid data.getDefault():
public function getDefault(): static {
$default = new static();
if (!$default->isValid()) {
throw new \RuntimeException('Invalid default state');
}
return $default;
}
$this->app->bind('default-user', fn() => new User(['name' => 'Admin']));
config():
public function getDefault(): static {
return new static(config('app.defaults.' . env('APP_ENV')));
}
Custom Default Factories:
Create a DefaultFactory class to centralize default logic:
class DefaultFactory {
public static function user(): User {
return User::getDefault();
}
}
Dynamic Defaults via Plugins: Allow plugins to override defaults:
$this->app->singleton('default-user-plugin', fn() => new PluginDefaultUser());
Laravel Service Provider Extensions: Add default bindings in a dedicated provider:
class DefaultServiceProvider extends ServiceProvider {
public function register() {
$this->app->bind('default-user', fn() => User::getDefault());
}
}
app() for Flexibility:
Prefer app('default-user') over User::getDefault() for easier mocking in tests.class EmptyCollection implements DefaultInterface {
public function getDefault(): static {
return new static();
}
}
JsonResource:
class UserResource extends JsonResource implements DefaultInterface {
public function getDefault(): static {
return new static(new User());
}
}
How can I help you explore Laravel packages today?