MonkeysLegion is a high-performance, attribute-first PHP 8.4+ framework built for modern web applications and APIs. It leverages PHP 8.4 property hooks, strict types, and compiled DI to deliver a developer experience that rivals Laravel and Symfony โ with zero runtime compromise.
- PHP 8.4 Property Hooks โ Native getters/setters via property hooks across all packages
- Attribute-First Architecture โ Routes, validation, providers, and commands discovered via attributes
- MLC Configuration โ
.mlcfile format with env interpolation, cascading, and production compilation - Compiled DI Container โ Zero-overhead production builds with atomic cache writes
- 26 Integrated Packages โ Every component pinned to v2.0+ for API consistency
- PSR-15 Middleware Pipeline โ Native security headers, CORS, rate limiting, CSRF, and request ID
- Apex AI/ML โ Built-in AI provider abstraction with OpenAI, cost tracking, and embeddings
- 182-Test Suite โ Comprehensive PHPUnit 11 test coverage across all framework layers
| Category | Details |
|---|---|
| ๐ฏ PSR Compliant | PSR-7, PSR-11, PSR-14, PSR-15, PSR-16, PSR-17 |
| ๐ง Modular | 26 independent, composable packages |
| ๐ Auth | JWT, OAuth2, 2FA, API Keys, RBAC, Policies, remember-me |
| ๐๏ธ Database | Connection manager, QueryBuilder, migrations, entity scanner |
| ๐จ Templates | Custom engine with caching, layouts, and directives |
| ๐ Routing | Attribute-based, auto-discovered, grouped, middleware-aware |
| โก DI | PSR-11 container with compiled cache for production |
| ๐ Validation | Attribute-based validation with DTO binding |
| ๐ I18n | Multi-language with database and file loaders |
| ๐ง Mail | SMTP and API-based email delivery |
| ๐ Telemetry | OpenTelemetry-compatible metrics, tracing, and structured logging |
| ๐ช Events | PSR-14 event dispatcher with listener auto-discovery |
| ๐พ Cache | Redis, file, in-memory backends (PSR-16) |
| ๐จ Queue | Background job processing with workers and retry |
| ๐ Files | Unified storage, image processing, garbage collection |
| ๐ OpenAPI | Auto-generated API docs from route attributes |
| ๐ค AI/ML | Apex: OpenAI provider, cost tracking, embeddings |
| ๐ CLI | Attribute-discovered commands, schedule, dev-server |
| ๐ก๏ธ Security | OWASP headers, CORS, rate limiting, CSRF, maintenance mode |
| Package | Version | Description |
|---|---|---|
monkeyslegion-core |
^2.0 | Core utilities, helpers, and base contracts |
monkeyslegion-di |
^2.0 | PSR-11 dependency injection container |
monkeyslegion-http |
^2.0 | PSR-7/PSR-15/PSR-17 HTTP layer and security middleware |
monkeyslegion-router |
^2.1 | Attribute-based routing with auto-discovery |
monkeyslegion-database |
^2.0 | Connection manager, PDO abstraction, transactions |
monkeyslegion-query |
^2.0 | Fluent QueryBuilder with grammar compilation |
monkeyslegion-entity |
^2.0 | Entity scanner and metadata extraction |
monkeyslegion-migration |
^2.0 | Database migration generator and runner |
monkeyslegion-auth |
^2.1 | JWT, session guards, password hashing, RBAC |
monkeyslegion-validation |
^2.0 | Attribute-based validation and DTO binding |
monkeyslegion-cache |
^2.0 | PSR-16 cache: Redis, file, in-memory stores |
monkeyslegion-session |
^2.0 | Session manager with CSRF middleware |
monkeyslegion-template |
^2.0 | Template engine with caching and layouts |
monkeyslegion-events |
^2.0 | PSR-14 event dispatcher |
monkeyslegion-logger |
^2.0 | PSR-3 logger with rotating file handlers |
monkeyslegion-queue |
^1.2 | Queue factory, workers, and job dispatching |
monkeyslegion-schedule |
^1.1 | Task scheduling with cron expressions |
monkeyslegion-mail |
^1.1 | SMTP and API-based email |
monkeyslegion-i18n |
^2.1 | Internationalization and locale management |
monkeyslegion-telemetry |
^2.0 | Metrics, distributed tracing, request middleware |
monkeyslegion-files |
^2.0 | File storage, image processing, garbage collection |
monkeyslegion-mlc |
^3.2 | MLC config parser with env interpolation |
monkeyslegion-cli |
^2.0 | CLI kernel with attribute-discovered commands |
monkeyslegion-apex |
^1.0 | AI/ML abstraction: OpenAI, cost tracking |
monkeyslegion-openapi |
^1.0 | Auto-generated OpenAPI v3 documentation |
monkeyslegion-dev-server |
^1.0 | Built-in development server |
- PHP 8.4+ (uses property hooks and modern features)
- Composer 2.x
- MySQL/MariaDB/PostgreSQL/SQLite (any PDO-supported database)
- Redis (optional โ for caching, queues, sessions, and rate limiting)
# Install via Composer
composer create-project monkeyscloud/monkeyslegion my-app
# Or add to an existing project
composer require monkeyscloud/monkeyslegionmy-app/
โโโ app/
โ โโโ Controller/ # HTTP controllers with route attributes
โ โโโ Entity/ # Database entities
โ โโโ Provider/ # Custom service providers
โ โโโ Middleware/ # Custom middleware
โโโ bootstrap/
โ โโโ app.php # Application factory
โ โโโ env.php # Environment loader
โโโ config/ # MLC configuration files
โ โโโ app.mlc
โ โโโ auth.mlc
โ โโโ database.mlc
โ โโโ ...
โโโ public/
โ โโโ index.php # HTTP entry point
โโโ resources/
โ โโโ views/ # Templates
โโโ tests/ # PHPUnit test suite
โโโ var/
โ โโโ cache/ # Compiled container, templates
โ โโโ logs/ # Application logs
โโโ .env # Environment variables
โโโ composer.json
โโโ phpunit.xml
public/index.php
โโโ bootstrap/app.php
โโโ Application::create(basePath)
โโโ ENV cascade: .env โ .env.local โ .env.{APP_ENV} โ .env.{APP_ENV}.local
โโโ MLC config: config/*.mlc โ Loader โ Config (compiled in production)
โโโ Service Providers: AppConfig โ 19 providers โ DI Container
โโโ SAPI detection: HTTP โ Kernel | CLI โ CliKernel
โโโ run()
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ServerRequest::fromGlobals() โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ CoreRequestHandler (PSR-15 Pipeline) โ
โ โโโ SecurityHeadersMiddleware (OWASP) โ
โ โโโ TrustedProxyMiddleware โ
โ โโโ RequestIdMiddleware โ
โ โโโ CorsMiddleware โ
โ โโโ RateLimitMiddleware โ
โ โโโ MaintenanceModeMiddleware โ
โ โโโ SessionMiddleware โ
โ โโโ VerifyCsrfToken โ
โ โโโ AuthenticationMiddleware โ
โ โโโ Router โ Controller โ Response โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ SapiEmitter โ Client โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
public/index.php
<?php
declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
$app = require __DIR__ . '/../bootstrap/app.php';
$app
->withMiddleware([
App\Middleware\CustomMiddleware::class,
])
->withBindings([
App\Service\PaymentGateway::class => fn($c) => new App\Service\StripeGateway(
apiKey: $_ENV['STRIPE_API_KEY'],
),
])
->run();Migration from v1: Replace
HttpBootstrap::run()withApplication::create()->run(). The legacy class still works but triggers a deprecation notice.
MonkeysLegion uses .mlc files โ a clean, typed config format with env interpolation:
config/app.mlc
app {
name = "My Application"
url = "${env.APP_URL}"
locale = "en"
fallback_locale = "en"
timezone = "UTC"
}
config/database.mlc
database {
connections {
mysql {
driver = "mysql"
host = "${env.DB_HOST}"
port = 3306
database = "${env.DB_DATABASE}"
username = "${env.DB_USERNAME}"
password = "${env.DB_PASSWORD}"
charset = "utf8mb4"
}
}
}
config/auth.mlc
auth {
default_guard = "jwt"
jwt_secret = "${env.JWT_SECRET}"
access_ttl = 1800
refresh_ttl = 604800
password {
algorithm = "argon2id"
memory_cost = 65536
time_cost = 4
}
rate_limit {
max_attempts = 60
lockout_seconds = 60
}
}
Environment cascade: .env โ .env.local โ .env.{APP_ENV} โ .env.{APP_ENV}.local
Define routes using PHP 8 attributes with auto-discovery:
<?php
declare(strict_types=1);
namespace App\Controller;
use MonkeysLegion\Router\Attribute\Route;
use MonkeysLegion\Router\Attribute\Get;
use MonkeysLegion\Router\Attribute\Post;
use MonkeysLegion\Router\Attribute\Delete;
use Psr\Http\Message\ResponseInterface;
#[Route('/api/users', name: 'users')]
final class UserController
{
#[Get('/', name: 'index')]
public function index(): ResponseInterface
{
return json_response(['users' => []]);
}
#[Get('/{id:\d+}', name: 'show')]
public function show(int $id): ResponseInterface
{
return json_response(['id' => $id]);
}
#[Post('/', name: 'create')]
public function create(CreateUserRequest $request): ResponseInterface
{
// DTO is auto-validated via DtoBinder
return json_response(['created' => true], 201);
}
#[Delete('/{id:\d+}', name: 'delete')]
public function delete(int $id): ResponseInterface
{
return json_response(null, 204);
}
}use MonkeysLegion\Query\Query\QueryBuilder;
$qb = $container->get(QueryBuilder::class);
// Select
$users = $qb->select(['id', 'name', 'email'])
->from('users')
->where('status', '=', 'active')
->orderBy('created_at', 'DESC')
->limit(10)
->get();
// Joins
$posts = $qb->select(['posts.*', 'users.name as author'])
->from('posts')
->join('users', 'posts.user_id', '=', 'users.id')
->get();
// Transactions
$connection->transaction(function () use ($qb): void {
$qb->insert('orders', ['total' => 100]);
$qb->update('inventory', ['stock' => 'stock - 1']);
});use MonkeysLegion\Auth\Service\AuthService;
use MonkeysLegion\Auth\Middleware\AuthenticationMiddleware;
// Login
$result = $authService->login([
'email' => 'user@example.com',
'password' => 'secret',
]);
if ($result->isAuthenticated()) {
$tokens = $result->getTokens();
// $tokens['access_token']
// $tokens['refresh_token']
}
// Protect routes via middleware
#[Route('/admin', middleware: [AuthenticationMiddleware::class])]
final class AdminController { /* ... */ }Auth capabilities: JWT, OAuth2 (Google, GitHub), TOTP 2FA, password reset, API keys, RBAC, policies, rate limiting, token blacklisting, remember-me.
use MonkeysLegion\Validation\Attribute\Required;
use MonkeysLegion\Validation\Attribute\Email;
use MonkeysLegion\Validation\Attribute\MinLength;
final class CreateUserRequest
{
#[Required]
#[MinLength(3)]
public string $name;
#[Required]
#[Email]
public string $email;
#[Required]
#[MinLength(8)]
public string $password;
}
// In controller โ automatically validated and bound
#[Post('/users')]
public function create(CreateUserRequest $request): ResponseInterface
{
// Invalid data returns 422 with structured errors
}Create custom modular providers with attribute discovery:
<?php
declare(strict_types=1);
namespace App\Provider;
use MonkeysLegion\Config\Providers\AbstractServiceProvider;
use MonkeysLegion\Framework\Attributes\Provider;
use MonkeysLegion\Framework\Attributes\BootAfter;
use MonkeysLegion\Config\Providers\DatabaseProvider;
#[Provider(priority: 10, context: 'all')]
#[BootAfter(DatabaseProvider::class)]
final class PaymentProvider extends AbstractServiceProvider
{
public function getDefinitions(): array
{
return [
PaymentGateway::class => fn($c) => new StripeGateway(
apiKey: $_ENV['STRIPE_API_KEY'],
),
];
}
public function context(): string
{
return 'http'; // Only loaded during HTTP requests
}
}<!-- resources/views/welcome.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ $title }}</title>
</head>
<body>
<h1>Welcome, {{ $user.name }}</h1>
@if($posts)
<ul>
@foreach($posts as $post)
<li>{{ $post.title }}</li>
@endforeach
</ul>
@endif
</body>
</html>use MonkeysLegion\Template\Renderer;
public function index(Renderer $renderer): ResponseInterface
{
return $renderer->render('welcome', [
'title' => 'Home',
'user' => ['name' => 'John'],
'posts' => $this->getPosts(),
]);
}// Define event
final readonly class UserRegistered
{
public function __construct(public int $userId) {}
}
// Register listener
$provider->addListener(UserRegistered::class, function (UserRegistered $event): void {
// Send welcome email, audit log, etc.
});
// Dispatch
$dispatcher->dispatch(new UserRegistered($user->getAuthIdentifier()));use MonkeysLegion\Apex\AI;
$ai = $container->get(AI::class);
// Chat completion
$response = $ai->chat([
['role' => 'user', 'content' => 'Explain PHP property hooks.'],
]);
echo $response->content;
echo $response->usage->totalTokens;
// Embeddings
$vector = $ai->embed('Search query text');
// Cost tracking (built-in)
$cost = $ai->getCostTracker()->getTotalCost();use MonkeysLegion\Queue\Contracts\QueueInterface;
$queue = $container->get(QueueInterface::class);
// Dispatch job
$queue->push(new SendEmailJob($userId));
// Worker (CLI)
// php bin/ml queue:work --tries=3 --timeout=60use MonkeysLegion\Files\FilesManager;
use MonkeysLegion\Files\Image\ImageProcessor;
$files = $container->get(FilesManager::class);
$image = $container->get(ImageProcessor::class);
// Store upload
$path = $files->store($uploadedFile, 'avatars');
// Process image
$image->process($path, [
'resize' => [150, 150],
'format' => 'webp',
]);use MonkeysLegion\I18n\Translator;
$t = $container->get(Translator::class);
echo $t->trans('welcome.message'); // "Welcome!"
echo $t->trans('user.greeting', ['name' => 'John']); // "Hello, John"
$t->setLocale('es');
echo $t->trans('welcome.message'); // "ยกBienvenido!"use MonkeysLegion\Telemetry\Metrics\MetricsInterface;
use MonkeysLegion\Telemetry\Tracing\TracerInterface;
// Metrics
$metrics->counter('http_requests_total')->inc();
$metrics->histogram('response_time_ms')->observe($duration);
// Distributed tracing
$span = $tracer->startSpan('process_order');
// ... work ...
$span->end();// Activate: create var/maintenance.php
file_put_contents('var/maintenance.php', '<?php return [
"retry" => 600,
"message" => "Upgrading to v2.0...",
];');
// Bypass via secret: ?secret=bypass123
// Bypass via IP whitelist: configured in MiddlewareProvider
// Deactivate: remove the file
unlink('var/maintenance.php');# Cache compiled container for production
php bin/ml config:cache
# Clear container cache
php bin/ml config:clear
# Run migrations
php bin/ml migrate:run
# Create migration
php bin/ml make:migration CreateUsersTable
# Clear application cache
php bin/ml cache:clear
# List all routes
php bin/ml route:list
# Start queue worker
php bin/ml queue:work
# Run scheduled tasks
php bin/ml schedule:run
# Framework info
php bin/ml about<?php
declare(strict_types=1);
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
final class ApiVersionMiddleware implements MiddlewareInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler,
): ResponseInterface {
$request = $request->withAttribute('api_version', 'v2');
$response = $handler->handle($request);
return $response->withHeader('X-API-Version', '2.0');
}
}Register in config/middleware.mlc:
middleware {
global = [
"MonkeysLegion\\Http\\Middleware\\SecurityHeadersMiddleware",
"MonkeysLegion\\Http\\Middleware\\CorsMiddleware",
"App\\Middleware\\ApiVersionMiddleware"
]
}
MonkeysLegion ships with a comprehensive test suite (PHPUnit 11):
# Run tests
php vendor/bin/phpunit
# Run with testdox output
php vendor/bin/phpunit --testdox
# Run specific test
php vendor/bin/phpunit --filter=ApplicationTest
# Static analysis (PHPStan Level 9)
php vendor/bin/phpstan analyse| Test Class | Target | Tests |
|---|---|---|
CompiledContainerCacheTest |
DI compiled cache | 14 |
AttributeTest |
Provider & BootAfter attributes | 7 |
MaintenanceModeMiddlewareTest |
Maintenance mode bypass | 7 |
ProviderScannerTest |
Auto-discovery scanner | 4 |
AppConfigTest |
Provider aggregator & context | 7 |
ConfigLoaderTest |
MLC config loading | 4 |
ProviderDefinitionsTest |
All 19 service providers | 90+ |
ApplicationTest |
Boot lifecycle & container | 13 |
ExceptionHandlerTest |
Error handling (JSON/HTML) | 10 |
DatabaseUserProviderTest |
Auth user operations | 15 |
HttpBootstrapTest |
v1 deprecation | 1 |
| Total | 182 tests, 440 assertions |
<?php
declare(strict_types=1);
namespace Tests\Feature;
use MonkeysLegion\Framework\Application;
use PHPUnit\Framework\TestCase;
final class UserServiceTest extends TestCase
{
private Application $app;
protected function setUp(): void
{
$this->app = Application::create(basePath: dirname(__DIR__));
}
public function testContainerResolvesService(): void
{
$container = $this->app->boot();
$service = $container->get(UserService::class);
$this->assertInstanceOf(UserService::class, $service);
}
}# Compile DI definitions for zero-overhead resolution
php bin/ml config:cache
# Clear when definitions change
php bin/ml config:clearThe ConfigLoader automatically compiles .mlc files to PHP arrays in var/cache/config.compiled.php for production. No parsing overhead on subsequent requests.
; php.ini recommended settings
opcache.enable=1
opcache.validate_timestamps=0 ; Disable in production
opcache.max_accelerated_files=20000
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.jit=1255
opcache.jit_buffer_size=128M| Variable | Default | Description |
|---|---|---|
APP_ENV |
production |
Environment: production, staging, dev, testing |
APP_DEBUG |
false |
Enable debug mode (error details, stack traces) |
APP_URL |
โ | Application base URL |
APP_TIMEZONE |
UTC |
Default timezone |
DB_CONNECTION |
mysql |
Database driver |
DB_HOST |
127.0.0.1 |
Database host |
DB_PORT |
3306 |
Database port |
DB_DATABASE |
โ | Database name |
DB_USERNAME |
root |
Database user |
DB_PASSWORD |
โ | Database password |
JWT_SECRET |
โ | JWT signing key |
REDIS_HOST |
127.0.0.1 |
Redis host |
REDIS_PORT |
6379 |
Redis port |
For detailed API documentation, visit monkeyslegion.com/docs or explore the individual package repositories on GitHub.
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes (
git commit -m 'feat: add my feature') - Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
MonkeysLegion is open-source software licensed under the MIT License.
Created and maintained by the MonkeysCloud team.
- Documentation: monkeyslegion.com/docs
- Issues: github.com/MonkeysCloud/MonkeysLegion/issues
- Discussions: github.com/MonkeysCloud/MonkeysLegion/discussions
- PHP 8.4 property hooks & attribute-first architecture
- 26-package modular ecosystem pinned to v2.0+
- MLC configuration with env cascading & production compilation
- Compiled DI container with atomic cache writes
- PSR-15 middleware pipeline with OWASP security headers
- Comprehensive auth: JWT, OAuth2, 2FA, RBAC, remember-me
- Apex AI/ML abstraction with OpenAI, cost tracking & embeddings
- OpenAPI v3 auto-generation from route attributes
- CLI scaffolding:
make:controller,make:entity,make:migration,make:middleware,make:dto,make:event,make:listener,make:policy,make:job,make:service,make:test,make:factory,make:seeder,make:enum,make:observer,make:resource,make:command - Database seeder and factory system (
seed:run,make:seeder,make:factory) - Telemetry: OpenTelemetry-compatible metrics, distributed tracing
- Event broadcasting interface (
ShouldBroadcast) - Maintenance mode with IP/secret bypass (
ml down/ml up) - Tinker REPL (
ml tinker) - 182-test suite with PHPUnit 11
- Notifications package (email, SMS, Slack, push)
- WebSocket server with real-time broadcasting driver
- Database model factories for testing (
Factory::define()) - Rate limiting per-route via attributes
- API resource transformers & pagination
- GraphQL support with attribute-based schema
- Admin panel generator (CRUD scaffolding)
- Fibers-based async HTTP client
- Native Swoole/FrankenPHP runtime support
- Plugin marketplace
Built with โค๏ธ by MonkeysCloud