On this page
Quickstart
Gacela gives each PHP module a clear public boundary and leaves your domain model alone. In this guide you build a complete module and run it from the command line.
You build: one entry point you can run, one public module boundary, and one service with no Gacela code in it.
You need: PHP 8.3 or newer and Composer (opens in a new tab).
Installation
Gacela 2.6 requires PHP 8.3 or newer. Install it from Packagist (opens in a new tab):
composer require gacela-project/gacela:^2.6Start with the code you want to run
Write the caller first. It defines the only method the module has to expose: greet().
<?php
declare(strict_types=1);
use Gacela\Framework\Gacela;
use Module\Facade;
require __DIR__ . '/vendor/autoload.php';
Gacela::bootstrap(__DIR__);
$facade = new Facade();
echo $facade->greet('Alice');The call will flow like this:
example.php → Facade → Factory → GreeterCreate the directories for these classes:
mkdir -p src/Module/Service1. Expose the module through a Facade
The Facade is the module's public API. It holds no business logic: it passes the request on.
<?php
declare(strict_types=1);
namespace Module;
use Gacela\Framework\AbstractFacade;
/**
* @extends AbstractFacade<Factory>
*/
final class Facade extends AbstractFacade
{
public function greet(string $name): string
{
return $this->getFactory()
->createGreeter()
->greet($name);
}
}When you call getFactory(), Gacela resolves the Factory in the same namespace.
2. Construct the service in a Factory
The Factory builds the module's objects. Construction details stay out of the Facade and the service.
<?php
declare(strict_types=1);
namespace Module;
use Gacela\Framework\AbstractFactory;
use Module\Service\Greeter;
final class Factory extends AbstractFactory
{
public function createGreeter(): Greeter
{
return new Greeter();
}
}3. Add the application service
Greeter is plain PHP. It extends and imports nothing from Gacela.
<?php
declare(strict_types=1);
namespace Module\Service;
final class Greeter
{
public function greet(string $name): string
{
return "Hi, {$name}!";
}
}4. Run it
Map the Module\\ namespace to src/Module/ in Composer:
{
"autoload": {
"psr-4": {
"Module\\": "src/Module/"
}
}
}Rebuild the autoloader and run the entry point:
composer dump-autoload
php example.phpHi, Alice!That output proves the whole path works: Composer loaded the classes, Gacela found the module's Factory, and the Facade reached the service.
If it does not run
| Error | Check |
|---|---|
Class "Module\\Facade" not found |
Confirm the PSR-4 mapping, then run composer dump-autoload again |
Gacela cannot resolve Factory |
Confirm Factory.php is beside Facade.php, both use namespace Module, and the class name is exactly Factory |
vendor/autoload.php is missing |
Run composer install from the project root |
| Your PHP version is rejected | Run php -v; Gacela 2.6 requires PHP 8.3+ |
You now have a complete Gacela module. Add a Provider only when it needs another module or an infrastructure service. Add a Config only when it needs application settings.
Next steps
Pick the page for what your module needs next:
- Getting dependencies: choose the right wiring mechanism
- Provider: talk to another module through its Facade
- Config: expose application settings through typed getters
- Bindings and container services: set application-wide dependency rules
- Testing: bootstrap Gacela with isolated state in PHPUnit