REMEMBER PHP

MINTE9
2REMEMBER




Last update:   23-07-2021

Front controller

Bye.php

Until now our application has only one page (index.php) v1.2 Let's add another page (bye.php)
 CodeCopy
// bye.php

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

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();

$response = new Response("Goodbye!");
$response->send();
... 4 more rows
˄˄˄
 
http://tests.local/php/framework/bye.php
    // Goodbye!

Front.php

Let's extract the common code and create our first "real" framework! The trick is the usage of Request::getPathInfo() which removes the front controller script name (and its subdirectories if needed). ! A single entry PHP script is called front controller design pattern. Let's write front.php
 CodeCopy
// front.php

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

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();
$response = new Response();

$map = [
    '/hello' => __DIR__.'/hello.php',
    '/bye' => __DIR__.'/bye.php',
];

$path = $request->getPathInfo(); // look here

if (isset($map[$path])) {
    require $map[$path];
} else {
    $response->setStatusCode(404);
    $response->setContent('Page not found');
}

$response->send();
... 15 more rows
˄˄˄
 CodeCopy
// hello.php

$name = $request->get('name', 'World');
$response->setContent(sprintf('Hello %s',
    htmlspecialchars($name, ENT_QUOTES, 'UTF-8')));
... 1 more rows
˄˄˄
 CodeCopy
// bye.php

$response->setContent("Goodbye!");
 
http://tests.local/php/framework/front.php/hello
    // Hello World

http://tests.local/php/framework/front.php/bye
    // Goodbye!
... 1 more rows
˄˄˄

src/pages/

! We can secure the code futher by moving all pages outside the root and making the web server to always access the same script (.htaccess to front.php)
 CodeCopy
RewriteEngine on
RewriteBase /php/framework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ front.php [L,QSA]
... 1 more rows
˄˄˄
 
// hello.php -> src/pages/hello.php
// bye.php -> src/pages/bye.php

Templates

The setContent() method is repeaded in each page. Let's convert all pages to templates and move setContent() in front controller.
 CodeCopy
// front.php

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

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();
$response = new Response();

$map = [
    '/hello' => __DIR__.'/src/pages/hello.phtml', // Look here
    '/bye' => __DIR__.'/src/pages/bye.phtml',
];

$path = $request->getPathInfo();

if (isset($map[$path])) {
    ob_start();
    require $map[$path];
    $response->setContent(ob_get_clean()); // Look here
} else {
    $response->setStatusCode(404);
    $response->setContent('Not found');
}

$response->send();
... 17 more rows
˄˄˄
 CodeCopy
<!-- src/pages/hello.phtml -->

<?php $name = $request->get('name', 'World'); ?>

Hello <?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8');
 CodeCopy
<!-- src/pages/bye.phtml -->

<?= "Goodbye!" ?>
 
http://tests.local/php/framework/hello 
    // Hello World

http://tests.local/php/framework/bie 
    // Goodbye!
... 1 more rows
˄˄˄
Framework v2.0 Fork v2.0c Public Folder    (2/2)

Public folder

Now, move front controller to separate folder and ... extract the request query parameters.
 
front.php -> public/front.php
 CodeCopy
// public/front.php

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

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();
$response = new Response();

$map = [
    '/hello' => 'hello', // Look here
    '/bye' => 'bye',
];

$path = $request->getPathInfo();
if (isset($map[$path])) {
    ob_start();
    extract($request->query->all(), EXTR_SKIP); // Look here
    include sprintf(__DIR__.'/../src/pages/%s.phtml', $map[$path]);
    $response->setContent(ob_get_clean());
} else {
    $response->setStatusCode(404);
    $response->setContent('Not found');
}

$response->send();
... 18 more rows
˄˄˄
 CodeCopy
<!-- src/pages/hello.phtml -->

Hello <?= htmlspecialchars($name ?? "World", 
    ENT_QUOTES, 'UTF-8') ?>
 CodeCopy
RewriteEngine on
RewriteBase /php/framework/public/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ front.php [L,QSA]
... 1 more rows
˄˄˄
 
http://tests.local/php/framework/public/hello 
    // Hello World

http://tests.local/php/framework/public/hello?name=Fabian 
    // Hello Fabian
... 1 more rows
˄˄˄
Framework v2.2
Questions    
No. 87   Routing
CARD
86
96

        A B C D E F
🔔
1/2