Quickstart
This guide takes you from zero to a running MVC app in five steps.
1. Scaffold the app
vendor/bin/mvc create-app ./src/MyApp --name=MyApp --namespace=App\\MyApp
This generates:
src/MyApp/
├── Controllers/
├── Views/
├── assets/
│ ├── i18n/
│ │ └── en.json
│ ├── scripts/
│ │ └── main.js
│ └── styles/
│ └── main.css
├── MyAppApp.php
├── MyAppBootstrap.php
└── mvc.config.json
MyAppApp.php— extendsMvcWebApp; wire routes here.MyAppBootstrap.php— composition root; register settings, PDO, and services on the container.mvc.config.json— feature flags and paths (see Configuration Reference).
2. Define a controller
<?php
declare(strict_types=1);
namespace App\MyApp\Controllers;
use PhpMvc\Controllers\Controller;
use PhpMvc\Actions\Responses\ActionResponse;
use PhpMvc\Actions\Responses\View;
final class HomeController extends Controller
{
public function index(): ActionResponse
{
return $this->view();
}
public function show(int $id): ActionResponse
{
$model = (object) ['id' => $id, 'title' => "Item {$id}"];
return $this->view(model: $model);
}
}
3. Register routes
Open MyAppApp.php and register routes in the router() method:
<?php
declare(strict_types=1);
namespace App\MyApp;
use PhpMvc\MvcWebApp;
use PhpMvc\Routes\Router;
use PhpMvc\Routes\Route;
use PhpMvc\Routes\RouteMethod;
use PhpMvc\Routes\Path;
use App\MyApp\Controllers\HomeController;
final class MyAppApp extends MvcWebApp
{
protected function router(): Router
{
$router = new Router();
$router->register(Route::create(
RouteMethod::Get,
Path::create('/'),
HomeController::class,
'index',
));
$router->register(Route::create(
RouteMethod::Get,
Path::create('/items/{int:id}'),
HomeController::class,
'show',
));
return $router;
}
}
4. Create a view
Create src/MyApp/Views/Home/index.html:
<!DOCTYPE html>
<html>
<head><title>My App</title></head>
<body>
<h1>Hello from PHP MVC</h1>
<a href="/items/1">View item 1</a>
</body>
</html>
And src/MyApp/Views/Home/show.html:
<!DOCTYPE html>
<html>
<head><title>Item {{model->id}}</title></head>
<body>
<h1>{{model->title}}</h1>
</body>
</html>
5. Create the entrypoint
Create public/index.php:
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use DI\Container;
use PhpMvc\ResponseEmitter;
use Psr\Http\Message\ServerRequestFactoryInterface;
use App\MyApp\MyAppApp;
use App\MyApp\MyAppBootstrap;
$container = new Container();
MyAppBootstrap::register($container, __DIR__ . '/../');
$app = new MyAppApp(container: $container, basePath: __DIR__ . '/../');
$server = $_SERVER;
$method = is_string($server['REQUEST_METHOD'] ?? null) ? $server['REQUEST_METHOD'] : 'GET';
$scheme = (!empty($server['HTTPS']) && 'off' !== $server['HTTPS']) ? 'https' : 'http';
$host = is_string($server['HTTP_HOST'] ?? $server['SERVER_NAME'] ?? null)
? ($server['HTTP_HOST'] ?? $server['SERVER_NAME'])
: 'localhost';
$rawUri = $server['REQUEST_URI'] ?? null;
$uri = $scheme.'://'.$host.(is_string($rawUri) ? $rawUri : '/');
/** @var ServerRequestFactoryInterface $requestFactory */
$requestFactory = $container->get(ServerRequestFactoryInterface::class);
$request = $requestFactory->createServerRequest($method, $uri, $server);
ResponseEmitter::emit($app->handle($request));
6. Run the built-in server
php -S localhost:8080 -t public
Open http://localhost:8080 — you should see Hello from PHP MVC.
Next steps
- Configuration Reference — learn every
mvc.config.jsonkey. - Routing — typed path parameters, auth-protected routes.
- Views & Templates — template language reference.
- CLI Reference — all
mvccommands.