SimpleMVC is a micro MVC framework for PHP using FastRoute, PHP-DI, Plates and PHP-DI standard for HTTP messages.
This framework is mainly used as tutorial for introducing the Model-View-Controller architecture in modern PHP applications.
Installation
PowerShell |
---|
| composer create-project ezimuel/simple-mvc
|
Structure
Text Only |
---|
| |- config
| |- container.php --> DI Container Config (PHP-DI)
| |- route.php --> routing
|- public
| |- img
| |- index.php --> app entry-point
|- src
| |- Model
| |- View --> Plates views
| |- Controller --> ControllerInterface.php
|- test
| |- Model
| |- Controller
|
index.php
PHP |
---|
| <?php
declare(strict_types=1);
chdir(dirname(__DIR__));
require 'vendor/autoload.php';
use DI\ContainerBuilder;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use Nyholm\Psr7\Factory\Psr17Factory;
use Nyholm\Psr7Server\ServerRequestCreator;
use SimpleMVC\Controller\Error404;
use SimpleMVC\Controller\Error405;
$builder = new ContainerBuilder();
$builder->addDefinitions('config/container.php');
$container = $builder->build();
// Routing
$dispatcher = FastRoute\simpleDispatcher(function(RouteCollector $r) {
$routes = require 'config/route.php';
foreach ($routes as $route) {
$r->addRoute($route[0], $route[1], $route[2]);
}
});
// Build the PSR-7 server request
$psr17Factory = new Psr17Factory();
$creator = new ServerRequestCreator(
$psr17Factory, // ServerRequestFactory
$psr17Factory, // UriFactory
$psr17Factory, // UploadedFileFactory
$psr17Factory // StreamFactory
);
$request = $creator->fromGlobals();
// Dispatch
$routeInfo = $dispatcher->dispatch(
$request->getMethod(),
$request->getUri()->getPath()
);
switch ($routeInfo[0]) {
case Dispatcher::NOT_FOUND:
$controllerName = Error404::class;
break;
case Dispatcher::METHOD_NOT_ALLOWED:
$controllerName = Error405::class;
break;
case Dispatcher::FOUND:
$controllerName = $routeInfo[1];
if (isset($routeInfo[2])) {
foreach ($routeInfo[2] as $name => $value) {
$request = $request->withAttribute($name, $value);
}
}
break;
}
$controller = $container->get($controllerName);
$controller->execute($request);
|
route.php
PHP |
---|
| <?php
use SimpleMVC\Controller;
return [
[ 'GET', '/', Controller\Home::class ],
[ 'GET', '/hello[/{name}]', Controller\Hello::class ],
[ "HTTP Verb", "/route[/optional]", Controller\EndpointController::class ]
];
|
container.php
PHP |
---|
| <?php
use League\Plates\Engine;
use Psr\Container\ContainerInterface;
return [
'view_path' => 'src/View',
Engine::class => function(ContainerInterface $c) {
return new Engine($c->get('view_path'));
}
// PHP-DI configs
];
|
ControllerInterface.php
Each controller must implement this interface.
PHP |
---|
| <?php
declare(strict_types=1);
namespace SimpleMVC\Controller;
use Psr\Http\Message\ServerRequestInterface;
interface ControllerInterface
{
public function execute(ServerRequestInterface $request);
}
|