mirko-pagliai / simple-view-controller
A lightweight PHP framework focused exclusively on the Controller and View layers
Installs: 3
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/mirko-pagliai/simple-view-controller
Requires
- php: ^8.3
- josegonzalez/dotenv: ^4.0
- psr/log: ^3.0
- symfony/http-foundation: ^7.3|^8.0
- symfony/http-kernel: ^7.3|^8.0
- symfony/routing: ^7.3|^8.0
Requires (Dev)
- cakephp/cakephp-codesniffer: ^5.3
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.2.7 || ^12.1
- symfony/var-dumper: ^7.4|^8.0
This package is auto-updated.
Last update: 2026-01-03 09:19:34 UTC
README
simple-view-controller is a lightweight PHP framework focused exclusively on the Controller and View layers.
It is designed as a library, not as a full-stack framework, and intentionally omits models, ORMs, template engines, and dependency injection containers.
The goal is to provide a minimal, explicit, and predictable runtime for small web applications.
Design goals
- Explicit behavior over implicit conventions
- Minimal and stable public API
- No magic exposed to the user
- Framework as a library, not as an application
- Use Symfony components without adopting a full-stack approach
What the framework provides
- An
Applicationruntime to handle HTTP requests - Routing based on Symfony Routing
- A base
Controllerclass - A minimal
Viewabstraction - Automatic injection of the current
Requestinto theView - Automatic template resolution and rendering
- Centralized error handling (404 and 500)
- PSR-3 compatible logging
- Environment variable loading via dotenv
What the framework does NOT provide
By design, the framework does not include:
- Models or a data layer
- ORMs or database abstractions
- A dependency injection container
- A templating engine
- HTML helpers
- CLI tooling
- Code generation
- An application entry point (
index.php) - A global debug switch
All of these are application-level concerns.
Routing
Routing is based on Symfony Routing.
Routes can be defined in two supported ways.
Option 1: defining routes in config/routes.php (best way)
By default, the application will try to load routes from config/routes.php
The file must return a RouteCollection:
<?php declare(strict_types=1); use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; use App\Controller\HomeController; $routes = new RouteCollection(); $routes->add('home', new Route(path: '/', defaults: [ '_controller' => ['\App\Controller\HomeController', 'index'], ])); return $routes;
Option 2: passing routes directly to the Application
Alternatively, you can pass a RouteCollection instance as an application argument:
<?php declare(strict_types=1); use SimpleVC\Application; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; $routes = new RouteCollection(); $routes->add('home', new Route(path: '/', defaults: [ '_controller' => ['\App\Controller\HomeController', 'index'], ])); $app = new Application($routes); $response = $app->handle(); $response->send();
Controllers
Controllers must extend SimpleVC\Controller:
<?php declare(strict_types=1); namespace App\Controller; use SimpleVC\Controller; use Symfony\Component\HttpFoundation\Response; class HomeController extends Controller { public function index(): Response { //Here's something... } }
The runtime invokes controller methods.
What they return is interpreted by the runtime, which is responsible for producing the final Response.
The framework explicitly supports multiple controller styles.
Example 1: controller preparing the View (implicit rendering)
public function index(): void { $this->set('title', 'Home'); $this->set('message', 'Hello world'); }
In this case:
- the controller does not return anything
- the controller does not implicity call
render() - the runtime resolves the template automatically
- the runtime renders the template and produces the
Response
The runtime will automatically resolve the template as templates/{ControllerName}/{methodName}.php.
So in this example case it would be templates/Home/index.php.
Inside this template file there will be the variables $title and $text.
Example 2: controller explicitly calls the render() method (returns a Response)
public function index(): Response { $this->set('title', 'Home'); $this->set('message', 'Hello world'); return $this->render('Custom/stuff.php'); }
The result is like the previous case, but in this one it will use the templates/Custom/stuff.php file.
Example 3: controller directly returns a Response
public function index(): Response { return new Response('<strong>Hello world</strong>'); }
In this case, the returned Response is used directly by the runtime.
Views
The View abstraction is intentionally minimal.
- Variables are assigned by the controller
- The current
Requestis injected automatically - By default, the template is resolved and rendered by the runtime
Templates are plain PHP files.