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

Default Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package:

    composer require php-standard-library/default
    

    Ensure your composer.json includes the package under require.

  2. Implement the Interface: Add DefaultInterface to a class (e.g., User, ApiResponse) and define getDefault():

    use PHPStandardLibrary\Default\DefaultInterface;
    
    class User implements DefaultInterface
    {
        public function getDefault(): static
        {
            return new static([
                'name' => 'Anonymous',
                'email' => null,
                'active' => false,
            ]);
        }
    }
    
  3. First Use Case: Replace hardcoded or inconsistent defaults with the standardized method:

    // Before:
    $defaultUser = new User([]);
    
    // After:
    $defaultUser = User::getDefault();
    
  4. Leverage Laravel’s Service Container (Optional): Bind the default instance globally for dependency injection:

    // In AppServiceProvider@boot()
    $this->app->bind('default.user', fn() => User::getDefault());
    

Implementation Patterns

Usage Patterns

  1. Domain Models: Standardize default states for Eloquent models or DTOs:

    class Order implements DefaultInterface
    {
        public function getDefault(): static
        {
            return new static([
                'items' => collect(),
                'total' => 0,
                'status' => 'pending',
            ]);
        }
    }
    
  2. API Responses: Enforce consistent error/default responses:

    class ApiResponse implements DefaultInterface
    {
        public function getDefault(): static
        {
            return new static([
                'success' => false,
                'data' => null,
                'errors' => [],
            ]);
        }
    }
    
  3. Service Layer: Provide fallback instances for services:

    class PaymentService implements DefaultInterface
    {
        public function getDefault(): static
        {
            return new static(app('default.payment-gateway'));
        }
    }
    
  4. Testing: Replace mocks with standardized defaults:

    // In PHPUnit tests:
    $user = User::getDefault(); // Instead of createMock(User::class)
    

Workflows

  1. Retrofitting Existing Classes: Use traits or interfaces to add DefaultInterface without modifying constructors:

    trait HasDefault
    {
        public function getDefault(): static
        {
            return new static($this->defaultAttributes());
        }
    
        protected function defaultAttributes(): array
        {
            return [];
        }
    }
    
  2. Dynamic Defaults via Laravel Bindings: Override defaults per environment or feature flag:

    $this->app->when(User::class)
               ->needs('$default')
               ->give(fn() => config('app.debug') ? new User(['name' => 'Debug User']) : User::getDefault());
    
  3. Modular Architecture: Use defaults for plugin compatibility:

    // Plugin Defaults
    class PluginConfig implements DefaultInterface
    {
        public function getDefault(): static
        {
            return new static([
                'enabled' => false,
                'settings' => [],
            ]);
        }
    }
    

Integration Tips

  1. Laravel Facades: Extend facades to use defaults:

    // In a custom facade:
    public static function defaultUser()
    {
        return User::getDefault();
    }
    
  2. Form Requests: Set default values in form requests:

    public function rules()
    {
        return [
            'user_id' => 'sometimes|exists:users,id,' . User::getDefault()->id,
        ];
    }
    
  3. Validation: Use defaults in validation rules:

    $validator = Validator::make($data, [
        'quantity' => 'sometimes|integer|min:1,' . OrderItem::getDefault()->minQuantity,
    ]);
    
  4. Events: Dispatch events with default payloads:

    event(new OrderCreated(Order::getDefault()));
    

Gotchas and Tips

Pitfalls

  1. Circular Dependencies: Avoid circular references in getDefault() (e.g., User::getDefault() initializing a UserRepository that requires a User). Fix: Use Laravel’s container to resolve dependencies lazily.

  2. State Contamination: Shared default instances (e.g., singletons) may retain state across requests. Fix: Use immutable objects or reset state in getDefault():

    public function getDefault(): static
    {
        return new static($this->defaultAttributes())->resetState();
    }
    
  3. Performance Overhead: Eager initialization of heavy defaults (e.g., database queries) in getDefault(). Fix: Lazy-load defaults via Laravel’s container:

    public function getDefault(): static
    {
        return $this->app->make(static::class, ['attributes' => $this->defaultAttributes()]);
    }
    
  4. Testing Quirks: Tests may fail if getDefault() relies on unresolved bindings. Fix: Mock the container or use a test-specific default:

    // In tests:
    User::shouldReceive('getDefault')->andReturn(new User(['name' => 'Test User']));
    
  5. Interface Pollution: Overusing DefaultInterface can clutter class signatures. Fix: Use traits or composition for optional defaults:

    class User
    {
        use HasDefault;
    }
    

Debugging

  1. Default Not Working?:

    • Verify the class implements DefaultInterface.
    • Check for typos in getDefault() (PHP 8+ static return types help catch this).
    • Ensure no static overrides exist (e.g., final methods or abstract classes).
  2. Container Binding Conflicts: If binding a default globally, ensure it doesn’t override existing instances:

    // Bad: Overrides all User instances
    $this->app->bind(User::class, fn() => User::getDefault());
    
    // Good: Bind to a specific key
    $this->app->bind('default.user', fn() => User::getDefault());
    
  3. Runtime Errors:

    • Error: Call to undefined method. Cause: Forgot to implement getDefault() or the interface. Fix: Add the missing method or interface.
    • Error: Return type of User::getDefault() must be of type User. Cause: PHP 8+ static return type mismatch. Fix: Update the return type hint:
      public function getDefault(): User { ... }
      

Config Quirks

  1. Caching Defaults: Cache getDefault() results to avoid repeated instantiation:

    public function getDefault(): static
    {
        return Cache::remember('default.user', now()->addHour(), fn() => new static($this->defaultAttributes()));
    }
    
  2. Environment-Specific Defaults: Use Laravel’s config to switch defaults:

    public function getDefault(): static
    {
        $attributes = config('app.env') === 'local'
            ? ['name' => 'Local Dev']
            : $this->defaultAttributes();
        return new static($attributes);
    }
    
  3. Database-Backed Defaults: For dynamic defaults (e.g., per-tenant), fetch from the database:

    public function getDefault(): static
    {
        return new static(Tenant::query()->defaultUser()->first() ?? $this->defaultAttributes());
    }
    

Extension Points

  1. Custom Default Factories: Create a factory class to generate defaults:

    class UserDefaultFactory
    {
        public function create(): User
        {
            return User::getDefault()->withRoles(['guest']);
        }
    }
    
  2. Default Overrides: Allow runtime overrides via Laravel’s container:

    $this->app->when(User::class)
               ->needs('$defaultOverride')
               ->give(fn() => $defaultOverride ?? User::getDefault());
    
  3. Localization: Support language-specific defaults:

    public function getDefault(): static
    {
        $locale = app()->getLocale();
        return new static([
            'greeting' => trans("defaults.user.greeting.{$locale}"),
        ]);
    }
    
  4. Plugin System: Let plugins extend or replace defaults:

    // Plugin service provider:
    $this->app->extend('default.user', fn($default) => $default->mergePluginDefaults());
    
  5. Event-Based Defaults: Trigger events when defaults are generated:

    public function getDefault(): static
    {
        $instance = new static($this->defaultAttributes());
        event(new DefaultGenerated($instance));
        return $instance;
    }
    
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.
codraw/entity-migrator
codraw/doctrine-extra
codraw/aws-tool-kit
codraw/validator
codraw/workflow
codraw/open-api
codraw/cron-job
codraw/process
codraw/log
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony