Search by

elliephp / framework

A fast, modular PHP microframework focused on clean architecture, performance, and zero-bloat components.

Maintainers

Package info

gitlab.com/adoboligh1/Ellie-Framework/

Homepage

Issues

pkg:composer/elliephp/framework

Transparency log

Statistics

Installs: 10

Dependents: 1

Suggesters: 0

Stars: 0

1.0.9 2026-09-04 22:47 UTC

This package is not auto-updated.

Last update: 2026-09-04 22:50:43 UTC


README

A fast, modular PHP microframework focused on clean architecture, performance, and zero-bloat components.

Requirements

  • PHP 8.4 or higher
  • Composer
  • PDO extension

Installation

composer install
cp .env.example .env

Quick Start

1. Configure Environment

Edit .env file with your settings:

APP_NAME='ElliePHP'
APP_DEBUG=true
APP_TIMEZONE='UTC'
CACHE_DRIVER=file

2. Define Routes

Routes are defined in routes/router.php:

use ElliePHP\Application\Http\Controllers\WelcomeController;use ElliePHP\Components\Routing\Router;

Router::get('/', WelcomeController::class);
Router::post('/api/users', [UserController::class, 'create']);

3. Create Controllers

Controllers live in app/Controllers/:

namespace ElliePHP\Application\Controllers;

use Psr\Http\Message\ResponseInterface;

final readonly class WelcomeController
{
    public function process(): ResponseInterface
    {
        return response()->json([
            'message' => 'Hello World'
        ]);
    }
}

4. Add Middleware

Register global middleware in app/Configs/Middleware.php:

return [
    'global_middlewares' => [
        LoggingMiddleware::class,
        CorsMiddleware::class,
    ],
];

Dependency Injection

ElliePHP uses PHP-DI for automatic dependency injection. Controllers and services get their dependencies automatically:

final readonly class UserController
{
    public function __construct(
        private UserService $userService
    ) {
    }

    public function index(): ResponseInterface
    {
        $users = $this->userService->getAllUsers();
        return response()->json(['users' => $users]);
    }
}

Configure bindings in configs/Container.php. See docs/DEPENDENCY_INJECTION.md for details.

Helper Functions

Container

container(); // Get container instance
container(UserService::class); // Resolve service

Environment Variables

env('APP_NAME'); // Get environment variable
env('APP_DEBUG', false); // With default value

Configuration

config('middleware.global_middlewares'); // Get config value
config(['app.name' => 'MyApp']); // Set config values

HTTP

request(); // Get current request
response(200)->json(['data' => $data]); // Create JSON response

Caching

cache()->set('key', 'value', 3600); // Cache for 1 hour
cache()->get('key', 'default'); // Get cached value
cache('redis')->set('key', 'value'); // Use specific driver

Logging

report()->info('User logged in', ['user_id' => 123]);
report()->error('Something went wrong');
report()->exception($exception);

Path Helpers

root_path('config/app.php');
app_path('Controllers/UserController.php');
storage_path('logs/app.log');
routes_path('api.php');

Cache Drivers

Supported cache drivers:

  • file - File-based caching (default)
  • redis - Redis caching
  • sqlite - SQLite database caching
  • apcu - APCu memory caching

Configure in .env:

CACHE_DRIVER=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

Directory Structure

├── app/
│   ├── Configs/         # Configuration files
│   ├── Controllers/     # HTTP controllers
│   ├── Middlewares/     # Custom middleware
│   └── Services/        # Business logic services
├── public/
│   └── index.php        # Application entry point
├── routes/
│   └── router.php       # Route definitions
├── src/
│   ├── Kernel/          # Framework core
│   └── Support/         # Helper functions
├── storage/
│   ├── Cache/           # Cache files
│   └── Logs/            # Application logs
└── tests/               # Unit tests

Development

Run the built-in PHP server:

php -S localhost:8000 -t public

Visit: http://localhost:8000

Testing

composer test
composer test:coverage

Database Toolkit

ElliePHP includes a fluent query builder, portable schema builder, batched migrations, and lightweight models.

$database->schema()->create('stations', function ($table): void {
    $table->id();
    $table->uuid()->unique();
    $table->string('name');
    $table->json('settings')->nullable();
    $table->timestamps();
});

$stations = $database->table('stations')
    ->where('active', true)
    ->orderBy('name')
    ->paginate(perPage: 25);

Migration files return an anonymous Migration instance. Migrations run in filename order and are tracked in batches:

$migrator = new Migrator($database);
$migrator->migrate(root_path('database/migrations'));
$migrator->rollback(root_path('database/migrations'));
$migrator->reset(root_path('database/migrations'));

Applications using ElliePHP Console can register the included commands through their container-backed command list:

return [
    MigrateCommand::class,
    RollbackCommand::class,
    MigrationStatusCommand::class,
    MakeMigrationCommand::class,
];

This provides migrate, migrate:rollback --step=2, migrate:status, and make:migration create_stations.

Migrations are non-transactional by default because MySQL implicitly commits many schema changes. A data-only migration can opt into a transaction by overriding withinTransaction() and returning true.

Typed records provide Active Record persistence without global connections, magic properties, or reflection-based mapping:

final class Station extends Record
{
    public function __construct(
        public ?int $id,
        public string $name,
    ) {}

    public static function table(): string { return 'stations'; }

    public static function fromRow(array $row): static
    {
        return new static((int) $row['id'], (string) $row['name']);
    }

    protected function setKey(int|string $key): void { $this->id = (int) $key; }
    protected function values(): array { return ['name' => $this->name]; }
    public function key(): int|string|null { return $this->id; }
}

$stations = $database->records(Station::class);
$station = $stations->create(new Station(null, 'Ellie FM'));
$station->name = 'Ellie Radio';
$station->save();

For APIs, ApiResponse provides consistent response envelopes without forcing a particular controller architecture:

return $api->paginated(Station::query()->paginate(page: 1));

License

MIT License

Support