Gacela
2.1.0 release notes (opens in a new tab)
Colour theme

Docs Getting started

On this page

Quickstart

Gacela gives PHP modules a predictable public boundary without imposing rules on your domain model. This guide creates a complete module you can run from the command line.

You will build: one runnable entry point, one public module boundary, and one framework-independent service.

Before you start: use PHP 8.3 or newer and have Composer (opens in a new tab) available.

Installation

Gacela 2.1 requires PHP 8.3 or newer. Install it from Packagist (opens in a new tab):

composer require gacela-project/gacela:^2.1

Start with the code you want to run

Write the caller first. It defines the only API this module needs to expose: greet().

example.phpphp
<?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 flow behind that call will be:

example.php → Facade → Factory → Greeter

Create the directories for those classes:

mkdir -p src/Module/Service

1. Expose the module through a Facade

The Facade is the module's public API. It delegates the request instead of containing business logic.

src/Module/Facade.phpphp
<?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);
    }
}

Gacela resolves the sibling Factory automatically when getFactory() is called.

2. Construct the service in a Factory

The Factory owns object construction inside the module. This keeps construction details out of the Facade and the service itself.

src/Module/Factory.phpphp
<?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 ordinary PHP. It does not extend or import anything from Gacela.

src/Module/Service/Greeter.phpphp
<?php

declare(strict_types=1);

namespace Module\Service;

final class Greeter
{
    public function greet(string $name): string
    {
        return "Hi, {$name}!";
    }
}

4. Run it

Make sure Composer maps the Module\\ namespace to src/Module/:

composer.jsonjson
{
  "autoload": {
    "psr-4": {
      "Module\\": "src/Module/"
    }
  }
}

Then rebuild the autoloader and run the entry point:

composer dump-autoload
php example.php
Hi, Alice!

If you see that output, the complete resolution 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.1 requires PHP 8.3+

That is a complete Gacela module. Add a Provider only when it needs another module or infrastructure service, and add a Config only when it needs application settings.

Next steps

Continue according to what the module needs next: