power-modules/framework

A powerful modular PHP framework with encapsulated modules, each having its own DI container and explicit import/export mechanisms

v1.1.2 2025-09-22 11:49 UTC

This package is auto-updated.

Last update: 2025-09-22 12:33:26 UTC


README

CI Packagist Version PHP Version License: MIT PHPStan

A general-purpose modular architecture framework for PHP. Build applications where each module has its own dependency injection container, with carefully controlled sharing through explicit import/export contracts.

๐Ÿ’ก Versatile: Works well for CLI tools, data pipelines, background processors, APIs, and complex PHP applications that benefit from clear module boundaries.

โœจ Why Modular Framework?

  • ๐Ÿ”’ True Encapsulation: Each module has its own isolated DI container
  • โšก PowerModuleSetup: Extend module functionality without breaking encapsulation
  • ๐Ÿš€ Microservice Ready: Isolated modules can easily become independent services
  • ๐Ÿ“‹ Explicit Dependencies: Import/export contracts make relationships visible
  • ๐Ÿงช Better Testing: Test modules in isolation with their own containers
  • ๐Ÿ‘ฅ Team Scalability: Different teams can own different modules
  • ๐Ÿ”Œ Plugin-Ready: Third-party modules extend functionality safely

Quick Start

composer require power-modules/framework
use Modular\Framework\App\ModularAppBuilder;

$app = new ModularAppBuilder(__DIR__)
    ->withModules(
        \MyApp\Auth\AuthModule::class,
        \MyApp\Orders\OrdersModule::class,
    )
    ->build();

// Get any exported service
$orderService = $app->get(\MyApp\Orders\OrderService::class);

โšก PowerModuleSetup Extension System

A key feature of the framework is PowerModuleSetup - a mechanism that allows extending module functionality without breaking encapsulation. This is how the import/export system itself is built!

// Extend modules with powerful setups
$app = new ModularAppBuilder(__DIR__)
    ->withModules(UserModule::class, OrderModule::class)
    ->addPowerModuleSetup(new RoutingSetup())    // Add HTTP routing capabilities to modules
    ->addPowerModuleSetup(new EventBusSetup())   // Add event publishing and handling
    ->build();

Real-world extensions:

  • power-modules/router - HTTP routing with PSR-15 middleware
  • power-modules/events Event-driven architecture (Coming soon!)
  • Custom setups - Authentication, logging, validation, you name it!

Key benefits:

  • Modules remain completely isolated and testable
  • Extensions work across ALL modules automatically
  • No coupling between core framework and extensions
  • Enables building ecosystems of reusable functionality

๐Ÿš€ Microservice Evolution Path

Start with a modular monolith, evolve to microservices naturally:

// Today: Modular monolith
class UserModule implements PowerModule, ExportsComponents {
    public static function exports(): array {
        return [UserService::class];
    }
}

class OrderModule implements PowerModule, ImportsComponents {
    public static function imports(): array {
        return [ImportItem::create(UserModule::class, UserService::class)];
    }
}

Later: Independent microservices

  • UserModule โ†’ User API service
  • OrderModule โ†’ Order API service
  • Import/export contracts โ†’ HTTP API contracts
  • Minimal architectural changes needed

Your modules are designed with clear boundaries. When you're ready to scale, the module structure supports splitting them into separate services.

๐Ÿ“š Documentation

Guide Description
Getting Started Build your first module in 5 minutes
Architecture Deep dive into module system, containers, and lifecycle
Use Cases Examples for web apps, ETL pipelines, and more
API Reference Complete interface and class documentation
Advanced Patterns Plugin systems, composition patterns, performance tips
Migration Guide Convert existing applications to use the framework

Real-World Examples

Simple Module

class OrdersModule implements PowerModule
{
    public function register(ConfigurableContainerInterface $container): void
    {
        $container->set(OrderService::class, OrderService::class)
            ->addArguments([OrderRepository::class]);
    }
}

Module with Exports

class AuthModule implements PowerModule, ExportsComponents
{
    public static function exports(): array
    {
        return [UserService::class];
    }
    
    public function register(ConfigurableContainerInterface $container): void
    {
        $container->set(UserService::class, UserService::class);
        // Internal services stay private by default
        $container->set(PasswordHasher::class, PasswordHasher::class);
    }
}

Module with Imports

class OrdersModule implements PowerModule, ImportsComponents
{
    public static function imports(): array
    {
        return [ImportItem::create(AuthModule::class, UserService::class)];
    }
    
    public function register(ConfigurableContainerInterface $container): void
    {
        // UserService is now available for injection
        $container->set(OrderService::class, OrderService::class)
            ->addArguments([UserService::class]);
    }
}

Contributing

See CONTRIBUTING.md for development setup and guidelines.

License

MIT License. See LICENSE for details.