PHPackages                             simplemvc/skeleton - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. simplemvc/skeleton

ActiveProject[Framework](/categories/framework)

simplemvc/skeleton
==================

A skeleton application using SimpleMVC framework

0.2(3y ago)29148MITPHPPHP ^7.4 || ^8.0

Since Jul 25Pushed 3y ago4 watchersCompare

[ Source](https://github.com/simplemvc/skeleton)[ Packagist](https://packagist.org/packages/simplemvc/skeleton)[ RSS](/packages/simplemvc-skeleton/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (6)Versions (3)Used By (0)

Skeleton application for SimpleMVC
----------------------------------

[](#skeleton-application-for-simplemvc)

[![Build status](https://github.com/simplemvc/skeleton/workflows/PHP%20test/badge.svg)](https://github.com/simplemvc/skeleton/actions)

This is a skeleton web application for [SimpleMVC](https://github.com/simplemvc/framework) framework.

Quickstart
----------

[](#quickstart)

You can install the skeleton application using the following command:

```
composer create-project simplemvc/skeleton

```

This will create a `skeleton` folder containing a basic web application. You can execute the application using the PHP internal web server, as follows:

```
composer run-script start

```

The application will be executed at .

This skeleton uses [PHP-DI](https://php-di.org/) as DI container and [Plates](https://platesphp.com/)as template engine.

Configuration
-------------

[](#configuration)

The application is configured using the ([config/config.php](config/config.php)) file:

```
use App\Config\Route;
use Monolog\Logger;
use Psr\Container\ContainerInterface;

return [
    'routing' => [
        'routes' => Route::getRoutes(),
        'cache' => 'data/cache/route.cache'
    ],
    'database' => [
        'pdo_dsn' => 'sqlite:data/db.sqlite',
    ],
    'view' => [
        'path' => 'src/View',
        'folders' => [
            'admin' => 'src/View/admin'
        ],
    ],
    'logger' => [
        'name' => 'app',
        'path' => sprintf("data/log/%s.log", date("Y_m_d")),
        'level' => Logger::DEBUG,
    ],
    // Basic authentication
    'authentication' => [
        'username' => 'test',
        'password' => '1234567890'
    ],
    'bootstrap' => function(ContainerInterface $c) {
       session_start();
    }
];
```

Each section contains the configuration of the routing system (`routing`), database (`database`), etc.

Routing system
--------------

[](#routing-system)

The routing system uses a Route class as follows ([config/Route.php](config/Route.php)):

```
class Route
{
    public const LOGIN = '/login';
    public const LOGOUT = '/logout';
    public const DASHBOARD = '/admin/users';

    public static function getRoutes(): array
    {
        return [
            [ 'GET', '/', Controller\Home::class ],
            [ 'GET', '/hello[/{name}]', Controller\Hello::class ],
            [ ['GET', 'POST'], self::LOGIN, Controller\Login::class ],
            [ 'GET', self::LOGOUT, Controller\Logout::class ],
            [ 'GET', '/basic-auth', [BasicAuth::class, Controller\Secret::class]],
            // Admin section
            [ 'GET', '/admin/users[/{id}]', [Controller\AuthSession::class, Admin\Users\Read::class]],
            [ 'POST', '/admin/users/{id}', [Controller\AuthSession::class, Admin\Users\Update::class]],
            [ 'POST', '/admin/users', [Controller\AuthSession::class, Admin\Users\Create::class]],
            [ 'DELETE', '/admin/users/{id}', [Controller\AuthSession::class, Admin\Users\Delete::class]],
        ];
    }
}
```

THis class contains onlya static method that returns the list of routes as array. A route is an element of the array with an HTTP method, a URL and a controller class to be executed. The URL can be specified using the FastRoute [syntax](https://github.com/nikic/FastRoute/blob/master/README.md). The controller class can be specified also with a pipeline of controllers, as array.

For instance, the `GET /admin/users[/{id}]` route has a pipeline with `[Controller\AuthSession, Admin\Users\Read]`. The controllers in the pipeline are executed in order, that means first `Controller\AuthSession` and last `Admin\Users\Read`.

Routing cache
-------------

[](#routing-cache)

The configuration of the skeleton application enables a caching folder for the routes.

```
return [
    'routing' => [
        'routes' => Route::getRoutes(),
        'cache' => 'data/cache/route.cache'
    ],
    // ...
]
```

Every time you change a route, you need to clean the cache using the following command:

```
composer run-script clean

```

If you want to disable the cache you can just comment (or delete) the key from the configuration array, as follows:

```
return [
    'routing' => [
        'routes' => Route::getRoutes(),
        // 'cache' => 'data/cache/route.cache'
    ],
    // ...
]
```

Controller
----------

[](#controller)

Each controller in SimpleMvc implements the `ControllerInterface`, as follows:

```
namespace SimpleMVC\Controller;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

interface ControllerInterface
{
    public function execute(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface;
}
```

The `execute()` function accepts two parameters, the `$request` and the optional `$response`. These are [PSR-7](https://www.php-fig.org/psr/psr-7/) HTTP request and response objects. The response is typically used when you need to execute a pipeline of multiple controllers, where you may want to pass the response from one controller to another.

The return of the `execute()` function is a PSR-7 Response. For instance, the `Home` controller reported in the skeleton application is as follows:

```
namespace SimpleMVC\Controller;

use League\Plates\Engine;
use Nyholm\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use SimpleMVC\Controller\ControllerInterface;

class Home implements ControllerInterface
{
    protected Engine $plates;

    public function __construct(Engine $plates)
    {
        $this->plates = $plates;
    }

    public function execute(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        return new Response(
            200,
            [],
            $this->plates->render('home')
        );
    }
}
```

The `execute()` function returns a PSR-7 `Nyholm\Psr7\Response` object using the [nyholm/psr7](https://github.com/Nyholm/psr7)project.

Execute a controller pipeline
-----------------------------

[](#execute-a-controller-pipeline)

In the route configuration file you can specify an array of controller to be executed. For instance, you can speficy that the `Secret` controller needs HTTP authentication and you can implement the logic in a separate `Auth` controller. The `config/route.php` configuration contains an example:

```
use SimpleMVC\Controller;

return [
    // ...
    [ 'GET', '/basic-auth', [ BasicAuth::class, Controller\Secret::class ]]
];
```

The third element of the array is an array itself, containing the list of controller to be executed. The order of execution is the same of the array, that means `BasicAuth` will be executed first and `Secret` after.

If you want, you can halt the execution flow of SimpleMVC returning a [HaltResponse](https://github.com/simplemvc/framework/blob/main/src/Response/HaltResponse.php) object. This response is just an empty class that extends a PSR-7 request to inform SimpleMVC to **stop the execution**.

SimpleMVC provideds a [Basic Access Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication)using the [BasicAuth](https://github.com/simplemvc/framework/blob/main/src/Controller/BasicAuth.php) controller.

Dependecy injection container
-----------------------------

[](#dependecy-injection-container)

All the dependencies are managed using the [PHP-DI](https://php-di.org/) project.

The dependency injection container is configured in [config/container.php](config/container.php) file.

Front controller
----------------

[](#front-controller)

A SimpleMVC application is executed using the `public/index.php` file. All the HTTP requests pass from this file, that is called **Front controller**.

The front controller is as follows:

```
use DI\ContainerBuilder;
use SimpleMVC\App;
use SimpleMVC\Emitter\SapiEmitter;

$builder = new ContainerBuilder();
$builder->addDefinitions('config/container.php');

$app = new App($builder->build());
$app->bootstrap();
$request = App::buildRequestFromGlobals();
$response = $app->dispatch($request);
SapiEmitter::emit($response);
```

In this file we build the DI container, reading from the [config/container.php](config/container.php)file and we inject it to the SimpleMVC\\App class.

The application configuration is stored in the DI container with the `config` key.

We execute the `bootstrap` function. This is a special function used to initialize the application status, e.g [starting the PHP session](https://github.com/simplemvc/skeleton/blob/main/config/config.php#L40-L42).

After, we build the PSR-7 HTTP request using `App::buildRequestFromGlobals()` from the PHP global variables $\_GET, $\_POST, $\_SERVER, etc.

Then, we execute the `dispatch` function that executes the Controller(s) according to the route.

Finally, we render the PSR-7 response to the standard output using the `SapiEmitter`.

### Copyright

[](#copyright)

The author of this software is [Enrico Zimuel](https://github.com/ezimuel/) and other [contributors](https://github.com/simplemvc/skeleton/graphs/contributors).

This software is released under the [MIT](/LICENSE) license.

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~212 days

Total

2

Last Release

1180d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/75c7c511421feb14316a01d29a7566bd4fdd97147b5a4f3faa5a065f9d0a0193?d=identicon)[ezimuel](/maintainers/ezimuel)

---

Top Contributors

[![ezimuel](https://avatars.githubusercontent.com/u/475967?v=4)](https://github.com/ezimuel "ezimuel (17 commits)")

---

Tags

psr-7frameworkSimplemvcSkeleton

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/simplemvc-skeleton/health.svg)

```
[![Health](https://phpackages.com/badges/simplemvc-skeleton/health.svg)](https://phpackages.com/packages/simplemvc-skeleton)
```

###  Alternatives

[cakephp/cakephp

The CakePHP framework

8.8k18.5M1.6k](/packages/cakephp-cakephp)[originphp/framework

The OriginPHP framework

472.6k6](/packages/originphp-framework)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
