📗

PHP - Architecture

CatégorieCours

Cours de Julie Chaumard

To Do

ChaptersHomeworksExercisesWeeksDates
PHP423/06/2025
424/06/2025
💚

Book - Chapter 11 - P.493

  • Connolly, R. and Hoar, R. (2018). Fundamentals of Web Development (2nd ed.). Pearson.

Display in PHP

echo '<pre>';print_r($myArray);echo '</pre>';

Paths

Type of paths

Canonical

For the entire URL, not a short one

https://www.mydomain.com/images/logo.png

Absolut

Entire path from the root

/var/www/html/project/includes/init.php

Relative

A path based on the current location

../includes/header.php

Retrieve the path

SEO and paths

Portability

Project portability means the ability of a project to be moved or used in different environments (local server, remote server, new folder, new domain…) without needing to change the code.

If the project is portable, everything works without modification:

What makes a project non-portable: hard-coded absolute paths

How to make partable

1. Organisation des chemins

  • Définir une constante ROOT_DIR dans bootstrap.php avec realpath(__DIR__)
  • Utiliser ROOT_DIR pour toutes les inclusions PHP (require, include)
  • Éviter les chemins absolus codés en dur (ex: /Users/Julie/Desktop/monprojet/)
  • Utiliser dirname(__FILE__) ou __DIR__ au lieu de chemins relatifs complexes comme ../../

2. Gestion des URL

  • Définir une constante BASE_URL dans bootstrap.php à partir de $_SERVER
  • Utiliser <?= BASE_URL ?> pour toutes les URL dans le HTML (CSS, JS, liens)
  • Éviter d’écrire le nom de domaine en dur (ex: http://localhost/monprojet/)

3. Inclusion de fichiers PHP

  • Centraliser tous les require et include dans un fichier bootstrap.php
  • Utiliser require_once ROOT_DIR . '/includes/fichier.php' partout
  • Créer des chemins dynamiques pour les templates (header, footer, etc.)

4. Chemins vers les assets (CSS, JS, images)

  • Ne pas utiliser de chemins relatifs comme ../assets/css/style.css dans le HTML
  • Utiliser des chemins absolus à partir de la racine web /assets/... ou <?= BASE_URL ?>/assets/...

5. Structure des dossiers

  • Organiser clairement le projet (ex: /public, /includes, /config, /template-parts)
  • Mettre le point d’entrée (index.php) dans /public
  • Protéger les autres dossiers via .htaccess si besoin

6. Configuration (base de données, constantes)

  • Placer les infos sensibles (connexion BDD, clés API…) dans config.php
  • Ne jamais versionner ce fichier (ajouter à .gitignore)
  • Utiliser des variables d’environnement si possible (.env)

7. Redirections et formulaires

  • Utiliser BASE_URL dans les action="..." de formulaires
  • Utiliser header("Location: " . BASE_URL . "/page.php") pour les redirections

8. Déploiement

  • Tester sur serveur local ET distant (MAMP, XAMPP, OVH, o2switch…)
  • Vérifier que tous les chemins fonctionnent après déplacement du projet
  • S’assurer qu’il n’y a aucune dépendance au chemin local du développeur

Bootstrap.php

A file to give the root instruction of your project.

To automatically define the path to not have to change it when you change the web server of your project

DOCUMENT_ROOT = /home/juliechaat/www
 		 ROOT_DIR = /home/juliechaat/www/tutos/web_dev/practice/exercices
 		 
// You get the relative path
tutos/web_dev/practice/exercices
<?php
// bootstrap.php

// Project root path
// define('ROOT_DIR', realpath(__DIR__));

// Relative path = substract the absolut project path ($_SERVER['DOCUMENT_ROOT'] ) to the path of the file (dirname(__DIR__))
$relativePath = str_replace($_SERVER['DOCUMENT_ROOT'], '', ROOT_DIR);

// The directory of the project
define('BASE_URL_REL', $relativePath);
// Protocol : http or https ?
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';

// the domain name
$host = $_SERVER['HTTP_HOST'];

An Improved Architecture

💡

Note: This is not a fully implemented MVC (Model-View-Controller) architecture, but it follows a similar logic by separating responsibilities and organizing code for better maintainability.

MCV architecture

MVC stands for Model - View - Controller. It’s a design pattern used to separate different parts of a web application:

This structure helps keep code modular, testable, and easier to maintain.

What would be needed for full MVC here?

To turn our current routing system into a real MVC structure, we would need to:

  1. Create a controllers/ folder

    Each controller handles requests, calls the model, and returns a view.

  1. Create a models/ folder

    Each model represents a type of data (User.php, Product.php, …) and handles database operations.

  1. Create a views/ folder

    Each view is a template (PHP, HTML, etc.) responsible only for presentation.

  1. Update the router to load the right controller based on the URL.

Practice

🎲

Implement an organized architecture in the sample project

funwebdev (project folder)
		├── exercices
				├── assets
				│   ├── css
				│   │   ├── footer.css
				│   │   ├── header.css
				│   │   └── main.css
				│   ├── fonts
				│   │   ├── SourGummy_Expanded-Light.ttf
				│   ├── images
				│   │   ├── 5855174537.jpg
				│   │   └── central-park.jpg
				│   └── js
				│       ├── countries.js
				│       └── exercise_1.js
				├── bootstrap.php
				├── index.php
				├── page-templates
				│   ├── countries.php
				│   ├── exercise_1.php
				│   ├── exercise_2.php
				│   ├── folder_2
				│   │   └── exercise_3.php
				│   └── infophp.php
				├── readme.md
				├── router.php
				├── template-parts
				│   ├── footer.php
				│   ├── head.php
				│   └── header.php
				├── test.php
				└── test2.php

exercices/index.php

<?php
require_once __DIR__ . '/bootstrap.php';
include ROOT_DIR . '/template-parts/head.php';
include ROOT_DIR . '/template-parts/header.php';
?>

<main>
    <h1>Home Page</h1>
</main>

<?php
include_once('template-parts/footer.php');
?>

exercices/.htaccess

⚠️

Be careful: when you upload the project files to your web host, .htaccess is a hidden file — don’t forget to include it!

RewriteEngine On

# Si le fichier ou dossier existe, ne rien faire
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Sinon, rediriger vers router.php
RewriteRule ^(.+)$ router.php?page=$1 [QSA,L]

exercices/router.php

<?php
require_once __DIR__ . '/bootstrap.php';

// This router dynamically loads pages from the "page-templates" folder
// It supports clean URLs using .htaccess rewriting rules

// $_GET contains the parameters passed in the URL, such as ?page=exercise_1
// $_GET['page'] can also include a subfolder, like folder_2/exercise_3
$page = $_GET['page'] ?? 'index';
//echo $_GET['page'];

// path to the page-templates to display
if ($page === "index") {
    $file = __DIR__ . "/" . $page . '.php';
} else {
    $file = __DIR__ . '/page-templates/' . $page . '.php';
}


// if the page-templates exists => display the page, else display error 404
if (file_exists($file)) {
    require_once $file;
} else {
    http_response_code(404);
    echo "<h1>404 - Page not found</h1>";
}

/template-parts/header.php

<header>
    <nav>
        <ul>
            <li><a href="<?php echo BASE_URL_REL ?>/exercise_1"><i class="fa-solid fa-user"></i>Exercise 1</a></li>
            <li><a href="<?php echo BASE_URL_REL ?>/exercise_2">Exercise 2</a></li>
            <li><a href="<?php echo BASE_URL_REL ?>/folder_2/exercise_3">Exercise 3</a></li>
            <li><a href="<?php echo BASE_URL_REL ?>/countries">Countries</a></li>
            <li><a href="#footer_page">Footer</a></li>
            <li><a href="<?php echo BASE_URL_REL ?>/exercise_2#footer_page">Exercise 2 Footer</a></li>
        </ul>
    </nav>
</header>

exercices/bootstrap.php

<?php
// bootstrap.php

// Project root path
define('ROOT_DIR', realpath(__DIR__));

// Protocol : http or https ?
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';

// the domain name
$host = $_SERVER['HTTP_HOST'];

// Relative path = substract the absolut project path ($_SERVER['DOCUMENT_ROOT'] ) to the path of the file (dirname(__DIR__))
$relativePath = str_replace($_SERVER['DOCUMENT_ROOT'], '', ROOT_DIR);

// The directory of the project
define('BASE_URL_REL', $relativePath);

💚

Agence digitale Parisweb.art
Tout savoir sur Julie, notre directrice de projets digitaux :
https://www.linkedin.com/in/juliechaumard/