PROGRAMMING

m9/ PHP
REMEMBERS




Last update:   23-07-2021

SoC

In computer science, Separation Of Concerns is a design principle for separting a computer program in different sections. Each section addresses a separate concern. This is called a modular program, which make sections easy to reused and replaced.

Simplex

Let's create our own namespace for the framework Simplex. Our application will have four different layers. /public/front.php /src/Simplex /src/NumberChecker /src/app.php ! The front controller is the only php code exposed to the client. It gets the Request and sends the Response. Provides a place to initialize the framework of the app.
 
// public/front.php

require_once __DIR__.'/../vendor/autoload.php';

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;

$request = Request::createFromGlobals();
$routes = include __DIR__.'/../src/app.php';

$context = new Routing\RequestContext();
$context->fromRequest($request);
$matcher = new Routing\Matcher\UrlMatcher($routes, $context);

$controllerResolver = new ControllerResolver();
$argumentResolver = new ArgumentResolver();

$framework = new Simplex\Framework(
    $matcher, $controllerResolver, $argumentResolver);
$response = $framework->handle($request);

$response->send();
... 12 lines
 
The reusable framework Simplex that abstacts the handling of Requests.
 
// src/Simplex/Framework.php

namespace Simplex;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;

Class Framework
{
    private $matcher;
    private $controllerResolver;
    private $argumentResolver;

    public function __construct(UrlMatcher $matcher,
                        ControllerResolver $controllerResolver,
                            ArgumentResolver $argumentResolver)
    {
        $this->matcher = $matcher;
        $this->controllerResolver = $controllerResolver;
        $this->argumentResolver = $argumentResolver;
    }

    public function handle(Request $request)
    {
        try {
            $request->attributes->add(
                $this->matcher->match($request->getPathInfo())
            );

            $controller =$this->controllerResolver->getController($request);
            $arguments =$this->argumentResolver
                ->getArguments($request, $controller);

            return call_user_func_array($controller, $arguments);
        } catch(ResourceNotFoundException $e) {
            return new Response('Not found', 404);
        } catch (\Exception $e) {
            return new Response('An error occured', 500);
        }
    }
}
... 32 lines
 
 
{
    "require-dev": {
        "phpunit/phpunit": "^8"
    },
    "require": {
        "symfony/http-foundation": "^5.2",
        "symfony/routing": "^5.2",
        "symfony/http-kernel": "^5.2"
    },
    "autoload": {
        "psr-4": {"": "src/"}
    }
}
... 7 lines
 
 
composer dump-autoload
Move the controller to NumberChecker\Controller\CheckNumberController.php Move the function in its own class NumberChecker\Model\NumberModel.php
 
// NumberChecker\Controller\CheckNumberController.php

namespace NumberChecker\Controller; // Look Here

use NumberChecker\Model\NumberModel;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class CheckNumberController
{
    public function index (Request $request, $no)
    {
        $model = new NumberModel();
        if ($model->isEven($no)) {
            return new Response("Yes, the number is even!");
        }
        return new Response("No, the number is odd of null.");
    }
}
... 10 lines
 
 
// NumberChecker\Model\NumberModel.php

namespace NumberChecker\Model;

class NumberModel
{
    public function isEven($no)
    {
        if (null === $no) return false;
        return $no % 2 == 0;
    }
}
... 4 lines
 
The application configuration.
 
// src/app.php

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing;

$routes = new Routing\RouteCollection();
$routes->add('isEven', new Routing\Route('/isEven/{no}', [
    'no' => null,
    '_controller' =>
        'NumberChecker\Controller\CheckNumberController::index',
            // Look Here
]));

return $routes;
... 5 lines
 
 
http://tests.local/php/framework/public/isEven/2 
    // Yes, the number is even!

http://tests.local/php/framework/public/isEven/23 
    // No, the number is odd of null.
Framework v6.0
Questions    
Testing

        A B C D E F
🔔
1/2