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

Proteus Laravel Package

stillat/proteus

Proteus provides a flexible, developer-friendly way to build and run dynamic “protean” objects in Laravel/PHP. Define behaviors, properties, and runtime composition with a clean API, useful for prototyping, extensible domain models, and data-driven object structures.

Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require stillat/proteus
    

    No service provider or facade needed—use the Proteus class directly.

  2. First Use Case: Reading Config

    use Stillat\Proteus\Proteus;
    
    $config = Proteus::read(config_path('app.php'));
    // Returns an array of the parsed config
    
  3. Where to Look First

    • Documentation: Check the GitHub repo (if available) for examples.
    • Source Code: The package is lightweight (~100 lines). Review src/Proteus.php for core logic.
    • Laravel Config Structure: Understand Laravel’s native config() helper and config.php structure.

Implementation Patterns

Core Workflows

1. Reading Config Files

$appConfig = Proteus::read(config_path('app.php'));
$customConfig = Proteus::read(base_path('config/custom.php'));
  • Use Case: Dynamically load config files without require or include.
  • Integration: Replace hardcoded require config_path('app.php'); in custom config loaders.

2. Modifying Config

$config = Proteus::read(config_path('app.php'));
$config['debug'] = env('APP_DEBUG', false);
Proteus::write(config_path('app.php'), $config);
  • Use Case: Update config values programmatically (e.g., during deployment or CLI tasks).
  • Workflow:
    1. Read → Modify → Write.
    2. Validate changes with Proteus::validate() (if extended).

3. Merging Configs

$base = Proteus::read(config_path('app.php'));
$override = Proteus::read(config_path('app-override.php'));
$merged = array_merge_recursive($base, $override);
Proteus::write(config_path('app.php'), $merged);
  • Use Case: Override settings dynamically (e.g., environment-specific configs).

4. CLI/Artisan Integration

// In a custom Artisan command
public function handle() {
    $config = Proteus::read(config_path('app.php'));
    $config['timezone'] = 'America/New_York';
    Proteus::write(config_path('app.php'), $config);
    $this->info('Config updated!');
}
  • Use Case: Runtime config adjustments via CLI.

5. Environment-Aware Loading

$env = app()->environment();
$configPath = config_path("app-{$env}.php");
if (file_exists($configPath)) {
    $config = Proteus::read($configPath);
}
  • Use Case: Load environment-specific configs (e.g., app-local.php, app-production.php).

Integration Tips

With Laravel’s Config System

  • Avoid Duplication: Use Proteus for non-standard config files (e.g., third-party or dynamic configs).
  • Cache Awareness: Clear config cache after writing:
    Proteus::write($path, $config);
    Artisan::call('config:clear');
    

With Package Development

  • Dynamic Configs: Let users override defaults via config/package-name.php:
    $defaults = Proteus::read(__DIR__.'/config.php');
    $userConfig = config_path('package-name.php');
    if (file_exists($userConfig)) {
        $defaults = array_merge_recursive($defaults, Proteus::read($userConfig));
    }
    

With Testing

  • Isolated Configs: Load test-specific configs:
    $testConfig = Proteus::read(base_path("tests/config/test.php"));
    

Gotchas and Tips

Pitfalls

  1. File Permissions

    • Writing config files requires writable permissions on the target file.
    • Fix: Ensure storage/ or config/ has 755 permissions or use storage_path('app/config-custom.php').
  2. Syntax Errors

    • Proteus::read() throws exceptions on invalid PHP syntax (unlike Laravel’s require).
    • Debug: Use Proteus::validate($config) (if implemented) or wrap in a try-catch.
  3. Recursive Merging Quirks

    • array_merge_recursive may not behave as expected with nested arrays.
    • Tip: Use array_replace_recursive for deeper overrides:
      $merged = array_replace_recursive($base, $override);
      
  4. Caching Interactions

    • Writing configs does not auto-clear Laravel’s config cache.
    • Workaround: Call Artisan::call('config:clear') or use config()->clear().
  5. Non-Standard Config Files

    • Proteus assumes PHP files with return []; structure.
    • Fix: Pre-process non-standard files or extend the package.

Debugging Tips

  1. Inspect Raw Config

    $raw = file_get_contents(config_path('app.php'));
    var_dump($raw); // Check for syntax issues
    
  2. Validate Before Writing

    $config = Proteus::read($path);
    if (isset($config['invalid_key'])) {
        throw new \RuntimeException('Invalid config detected!');
    }
    
  3. Log Changes

    $old = Proteus::read($path);
    Proteus::write($path, $new);
    \Log::info('Config updated', ['old' => $old, 'new' => $new]);
    

Extension Points

  1. Custom Parsers

    • Extend Proteus to support non-PHP config files (e.g., JSON, YAML):
      class JsonProteus extends Proteus {
          public static function read(string $path) {
              return json_decode(file_get_contents($path), true);
          }
      }
      
  2. Validation Rules

    • Add schema validation:
      use Stillat\Proteus\Contracts\Validatable;
      
      class ValidatedProteus implements Validatable {
          public function validate(array $config): bool {
              return isset($config['required_key']);
          }
      }
      
  3. Event Dispatching

    • Trigger events on read/write:
      Proteus::onWrite(function ($path, $config) {
          event(new ConfigUpdated($path, $config));
      });
      
  4. Fallback Logic

    • Implement fallback configs:
      $config = Proteus::read($path) ?: Proteus::read($fallbackPath);
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport