Although I was familiar with software design patterns including MVC, it was only over the last two months that I had real commercial experience working with the MVC pattern on a web application framework. 

Model-View-Controller (MVC) is a software design pattern that advocates for the separation of concerns (SoC) and don’t repeat yourself (DRY) principles by grouping the concerns into the three main components. 

In a typical MVC structure, the model is responsible for fetching the raw data and molding it into user-friendly information. The view is responsible for presenting this data while the controller manages the process and the overall lifecycle of the request to the point of delegating the response.

An MVC project can have more components than the three described. In bigger projects a router can be added to handle URL routing when working with multiple controllers.The illustration below shows how the structure would look like:

MVC Request Flow

www.webdevelopmenthelp.net

Working with Slim

Slim is a PHP micro-framework designed to be fast and less bloated than other frameworks available by only providing minimal set of tools required for development. Slim is well documented and we’ve blogged about it quite actively in the best as a very sound, robust and efficient micro-framework for PHP that’s not only easy to learn but very easy to integrate into any existing platforms.

Building the Application

A Slim app contains routes that respond to specific HTTP requests. Each route invokes a callback and returns an HTTP response. To get started, you first instantiate and configure the Slim application. Next, you define your application routes. Finally, you run the Slim application.

$container = new SlimContainer;
$app = new SlimApp($container);

In the example above, we instantiate a new container (based off the Pimple container) which contains all the routes, models and controllers that our app will use stored. For example:

$container[‘ClassA’] = function($c) {
    return new AppControllerClassA($c);
};
$container[‘ModelA’] = function($c) {
    return new AppModelModelA($c);
};

The most important part, is establishing our routes. Slim is built on-top of FastRoute and lets you effortlessly create new routes. Lets add a POST and GET method, and give an example of how you can pass parameters into your PHP code:

$app->get(‘/test’, [‘AppControllerClassA’, ‘getTestPage’]);
$app->post(‘/save’, [‘AppControllerClassA’, ‘saveTestPage’]);

Finally, we can run the app and handle the request:

$app->run();

Accessing the Elements

A controller can be designed to have many methods which can be called upon different HTTP requests. When calling a controller method, we can use Slim’s callable resolver scope allowing us to define an array that specifies its class and the method to run. Each method we define takes 3 arguments, the request, the response and the optional arguments.

Request

The first argument is a PsrHttpMessageServerRequestInterface object that represents the current HTTP request. Whilst Slim’s request object conforms to the PSR-7 standard HTTP request object, it provides us with a couple of additional methods: getOriginalMethod, isMethod, isGet, isPost, isPut, etc.

Response

The second argument is a PsrHttpMessageResponseInterface object that represents the current HTTP response. Similar to the request object, whilst conforming to the PSR-7 standard HTTP response object, it also provides us with additional methods including: write, withRedirect, withJson, isEmpty, isInformational, etc.

Arguments

The third argument is an associative array that contains values for the current route’s named placeholders.

Container

As our models are stored in the container, we can access them pretty effortly through Slim by calling:

$modelA = $container->get(‘ModelA’);
$modelB = $container->get(‘ModelB’);

Reading Request Data

To read JSON or XML data from a HTTP Request, Slim provides a built method called ‘getParsedBody()’ which will translate the data into associative arrays.

$requestData = $request->getParsedBody();
$inputId = $requestData[‘id’];

We pass in arguments to the controller by binding them in the route we define:

$app->get(‘/user/{id}’, [‘AppControllerUser’, ‘getById’]);
class User {
    public function getById($request, $response, array $args = [])
    {
        // We can now access $args[‘id’]
    }
}

Responding with Data

Slim’s response object allows us to send either a HTML response or write a body output:

// Send text / HTML
$response->write(‘Example output’);
// Output a JSON object
$response->withJson([
    ‘Key’ => ‘value’,
    ‘keyB’ => ‘value’
]);

Integrating a View

Slim version 3 no longer provides a render function and instead lets you easily integrate with an array of independant packages. You could use slim/twig-view or our favourite, Plates native PHP templates.

Model and Data Objects

In any MVC application, you’d want to define a model layer that’s solely responsible for any business logic and database interaction. The code should be interoperable and ideally, easy to drop right into other projects without any coupling to other code fragments. Using the container, you can easily create an abstract model which all other classes extend, that provide you with a simple DAL (database abstraction layer) such as Doctrine or Pixie.

10