PHP

  minte9
REMEMBERS




Last update:   28-03-2022

Simplex

Our application will have four different layers.
 
/**
 * public/front.php
 * 
 * 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, easy to reused and replaced.
 * 
 * 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.
 * It provides a place to initialize the framework of the app.
 * 
 * ------------------------------------------------------------
 * 
 * composer.json
 * {
 *      "require": {
 *          "symfony/routing": "^6.0",
 *          "symfony/http-foundation": "^6.0",
 *          "symfony/http-kernel": "^6.0"
 *      },
 *      "autoload": {
 *          "psr-4": {"": "src/"}
 *      }
 * }
 * composer dump-autoload
 * php -S localhost:8000 public/front.php
 * 
 * http://localhost:8000/isEven/24
 *      The number is Even
 * http://localhost:8000/isEven/123
 *      The number is Odd
 */

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

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;

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

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

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

$framework = new Simplex\Framework( // Simplex framework
    $matcher, $controllerResolver, $argumentResolver
);

$response = $framework->handle($request);
$response->send();

App

The application configuration src/app.php
 
// src/app.php

use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

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

return $routes;

Simplex

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);
        }
    }
}

Render

The render controller is moved to NumberChecker module.
 
// src/NumberChecker/Controller/CheckNumberController.php

namespace NumberChecker\Controller;

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("The number is even");
        }
        return new Response("The number is odd of null");
    }
}
 
// src/NumberChecker/Model/NumberModel.php

namespace NumberChecker\Model;

class NumberModel
{
    public function isEven($no)
    {
        return $no % 2 == 0;
    }
}

Questions     github Framework
Symfony v5
        A B C D E F
🔔
1/1