yonis-savary / cube
Simple Web Framework for PHP8+
Requires
- cboden/ratchet: ^0.4.4
- psr/log: ^3.0.2
- react/http: ^1.10
- symfony/process: 7.2.0
Requires (Dev)
- friendsofphp/php-cs-fixer: v3.70.0
- phpunit/phpunit: 11.5.3
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-16 09:49:59 UTC
README
Cube is a light framework that provides every essential tool needed to build back-end projects and automation tools.
You can find the framework's documentation in the /docs directory !
AI Usage
Cube source code should not be generated : AI can be used to improve readability or performance, but source code should still be handwritten.
Tests can be automatically written by agents.
🧰 Features
-
🌐 Web
- Fast Routing
- Request Validation
- Middleware
- Static File Serving
- Unix Socket Server (for internal APIs)
-
🔩 Framework
- Full DocBlock support ! (No magic methods, every type is documented)
- PHP Configuration
- CLI Commands
- Routine tools (Scheduling / Queueing)
-
🌳 Environment
- Cache (Files or Redis)
- Session (Files, DB or Redis)
- Directory manipulation (Local Disk / FTP)
- PSR Logging
-
💿 Data
- Model Manipulation (Supported DBMS : MySQL/MariaDB, SQLite, Postgres)
- Automatic Model Generation !
- DB Migration system !
- Password Authentication System (+ Support for Custom Authentication)
🔥 Installation
# Install in your repository composer require yonis-savary/cube # Install server base files such as Public/, .gitignore... cp -r vendor/yonis-savary/cube/server/* .
🔍 Cube's Look
A controller is discovered on its own, its routes are declared next to their callbacks
class ProductController extends Controller { public function __constructor( protected MyProductService $productService ) { // Dependency injection is supported for many features! } public function routes(Router $router): void { $router->addRoutes( Route::get('/product/{int:id}', [self::class, 'getProduct']), Route::post('/product', [self::class, 'storeProduct']), //... ); } // Slug values is resolved through parameter type (404 when it does not exist) public static function getProduct(Request $request, Product $product) { return $product; } // The request is validated before the callback runs (422 when it is not) public static function storeProduct(StoreProductRequest $request) { $product = Product::fromRequest($request); $product->save(); return Response::json($product, StatusCode::CREATED); } }
Input shapes are declared once, in a Request subclass
class StoreProductRequest extends Request { public function getRules(): array { return [ 'name' => Param::string(), 'price_dollar' => Param::float(nullable: true), ]; } }
Queries are built fluently, and run on MySQL, Postgres or SQLite alike
$cheapest = Product::select(with: ['provider']) ->where('price_dollar', 20, '<') ->order('price_dollar', 'ASC') ->limit(10) ->fetch(); $product = Product::find(4); $product->name = 'monitor'; $product->save();
A command is a class too : this one runs with php do app:count-products
class CountProducts extends Command { public function execute(Args $args): int { Console::log(Product::select()->count()); return 0; } }
📈 Development
# Testing the framework make test