Build modular PHP applications.
Split your application into modules that talk through one door. Everything behind it stays private.
The only door. Every other module in your application talks to this module through its Facade, and through nothing else. Change what is behind it freely: nobody outside can depend on what they cannot reach. Read about the Facade
Wires the inside. The Factory builds this module's own services and hands them their dependencies. It is where object construction lives, so your domain classes never have to know how they were made. Read about the Factory
Reaches outside. When the module needs something another module owns, the Provider resolves it. Extra-dependencies enter here and nowhere else, which keeps the coupling in one readable file. Read about the Provider
Reads the settings. The Config gives the Factory typed access to the project's configuration files, so a value can change per environment without any class inside the module learning where it came from. Read about the Config
Quickstart
A module in three files
This is the whole ceremony: a Facade in front, a Factory wiring a service behind it, and one bootstrap call at your entry point. The Facade resolves its sibling Factory automatically.
use Gacela\Framework\Gacela;
use Module\Facade;
require __DIR__ . '/vendor/autoload.php';
Gacela::bootstrap(__DIR__);
$facade = new Facade();
echo $facade->greet('Alice'); # Hi, Alice!namespace Module;
use Gacela\Framework\AbstractFacade;
/**
* @method Factory getFactory()
*/
final class Facade extends AbstractFacade
{
public function greet(string $name): string
{
return $this->getFactory()
->createGreeter()
->greet($name);
}
}namespace Module;
use Gacela\Framework\AbstractFactory;
use Module\Service\Greeter;
final class Factory extends AbstractFactory
{
public function createGreeter(): Greeter
{
return new Greeter();
}
}namespace Module\Service;
final class Greeter
{
public function greet(string $name): string
{
return "Hi, $name!";
}
}Features
Beyond the basics
- Container DI Bindings, tags, hooks, definitions, scopes and lazy services
- Caching Three layers: framework resolution, cacheable methods, file cache
- Tooling cache:warm, doctor, debug:module, debug:graph, profile:report
- Lifecycle events Zero-cost bootstrap, config, container and cache events for tracing
- Health checks Per-module status for the doctor CLI and HTTP endpoints
- Inject attribute #[Inject] on constructors, properties and setters
- Provides attribute Declarative #[Provides] for provider service registration
- Testing GacelaTestCase: bootstrap isolation and event-backed assertions
Get started
Start your first module
composer require gacela-project/gacela:^2.1