Bootstrap
Bootstrap est le code d'amorçage qui initialise l'environnement, crée le conteneur d'injection de dépendances (DI) et lance l'application. Nous allons discuter :
- comment il est configuré à l'aide des fichiers NEON
- comment distinguer les modes production et développement
- comment créer le conteneur DI
Les applications, qu'elles soient web ou des scripts exécutés depuis la ligne de commande, commencent leur exécution par une
forme d'initialisation de l'environnement. Autrefois, un fichier nommé par exemple include.inc.php
s'en chargeait,
inclus par le fichier initial. Dans les applications Nette modernes, il a été remplacé par la classe Bootstrap
,
que vous trouverez dans le fichier app/Bootstrap.php
en tant que partie de l'application. Elle peut ressembler à
ceci, par exemple :
use Nette\Bootstrap\Configurator;
class Bootstrap
{
private Configurator $configurator;
private string $rootDir;
public function __construct()
{
$this->rootDir = dirname(__DIR__);
// Le Configurator est responsable de la configuration de l'environnement et des services de l'application.
$this->configurator = new Configurator;
// Définit le répertoire pour les fichiers temporaires générés par Nette (par exemple, les templates compilés)
$this->configurator->setTempDirectory($this->rootDir . '/temp');
}
public function bootWebApplication(): Nette\DI\Container
{
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}
private function initializeEnvironment(): void
{
// Nette est intelligent et le mode développement est activé automatiquement,
// ou vous pouvez l'activer pour une adresse IP spécifique en décommentant la ligne suivante :
// $this->configurator->setDebugMode('secret@23.75.345.200');
// Active Tracy : l'ultime "couteau suisse" pour le débogage.
$this->configurator->enableTracy($this->rootDir . '/log');
// RobotLoader : charge automatiquement toutes les classes dans le répertoire sélectionné
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
}
private function setupContainer(): void
{
// Charge les fichiers de configuration
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
}
}
index.php
Le fichier initial pour les applications web est index.php
, situé dans le répertoire public www/
.
Il demande à la classe Bootstrap d'initialiser l'environnement et de créer le conteneur DI. Ensuite, il obtient le service
Application
à partir de celui-ci, qui lance l'application web :
$bootstrap = new App\Bootstrap;
// Initialisation de l'environnement + création du conteneur DI
$container = $bootstrap->bootWebApplication();
// Le conteneur DI crée l'objet Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
// Lancement de l'application Nette et traitement de la requête entrante
$application->run();
Comme vous pouvez le voir, la classe Nette\Bootstrap\Configurator aide à configurer l'environnement et à créer le conteneur d'injection de dépendances (DI), que nous allons maintenant présenter plus en détail.
Mode Développement vs Production
Nette se comporte différemment selon qu'il s'exécute sur un serveur de développement ou de production :
- 🛠️ Mode Développement (Development)
- Affiche la barre de débogage Tracy avec des informations utiles (requêtes SQL, temps d'exécution, mémoire utilisée)
- En cas d'erreur, affiche une page d'erreur détaillée avec les appels de fonction et le contenu des variables
- Rafraîchit automatiquement le cache lors de la modification des templates Latte, des fichiers de configuration, etc.
- 🚀 Mode Production (Production)
- N'affiche aucune information de débogage, toutes les erreurs sont écrites dans le journal
- En cas d'erreur, affiche l'ErrorPresenter ou une page générique “Erreur Serveur”
- Le cache n'est jamais rafraîchi automatiquement !
- Optimisé pour la vitesse et la sécurité
La sélection du mode se fait par autodétection, il n'est donc généralement pas nécessaire de configurer quoi que ce soit ou de basculer manuellement :
- mode développement : sur localhost (adresse IP
127.0.0.1
ou::1
) s'il n'y a pas de proxy présent (c'est-à-dire son en-tête HTTP) - mode production : partout ailleurs
Si nous voulons activer le mode développement dans d'autres cas, par exemple pour les programmeurs accédant depuis une
adresse IP spécifiques, nous utilisons setDebugMode()
:
$this->configurator->setDebugMode('23.75.345.200'); // un tableau d'adresses IP peut également être fourni
Nous recommandons vivement de combiner l'adresse IP avec un cookie. Nous stockons un jeton secret, par exemple
secret1234
, dans le cookie nette-debug
, et activons ainsi le mode développement pour les programmeurs
accédant depuis une adresse IP spécifique et ayant également le jeton mentionné dans le cookie :
$this->configurator->setDebugMode('secret1234@23.75.345.200');
Nous pouvons également désactiver complètement le mode développement, même pour localhost :
$this->configurator->setDebugMode(false);
Attention, la valeur true
active le mode développement de manière forcée, ce qui ne doit jamais se produire sur
un serveur de production.
Outil de Débogage Tracy
Pour faciliter le débogage, nous activons également l'excellent outil Tracy. En mode développement, il visualise les erreurs, et en mode production, il enregistre les erreurs dans le répertoire spécifié :
$this->configurator->enableTracy($this->rootDir . '/log');
Fichiers Temporaires
Nette utilise un cache pour le conteneur DI, RobotLoader, les templates, etc. Il est donc nécessaire de définir le chemin vers le répertoire où le cache sera stocké :
$this->configurator->setTempDirectory($this->rootDir . '/temp');
Sous Linux ou macOS, définissez les permissions
d'écriture pour les répertoires log/
et temp/
.
RobotLoader
En règle générale, nous voudrons charger automatiquement les classes à l'aide de RobotLoader, nous devons donc le démarrer et le laisser charger les classes du
répertoire où se trouve Bootstrap.php
(c'est-à-dire __DIR__
), ainsi que de tous ses
sous-répertoires :
$this->configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
Une approche alternative consiste à laisser les classes être chargées uniquement via Composer tout en respectant PSR-4.
Fuseau Horaire
Via le configurateur, vous pouvez définir le fuseau horaire par défaut.
$this->configurator->setTimeZone('Europe/Prague');
Configuration du Conteneur DI
Une partie du processus de démarrage est la création du conteneur DI, ou factory d'objets, qui est le cœur de toute l'application. Il s'agit en fait d'une classe PHP générée par Nette et stockée dans le répertoire cache. La factory produit les objets clés de l'application, et à l'aide des fichiers de configuration, nous lui indiquons comment les créer et les configurer, influençant ainsi le comportement de toute l'application.
Les fichiers de configuration sont généralement écrits au format NEON. Dans un chapitre séparé, vous apprendrez tout ce qui peut être configuré.
En mode développement, le conteneur est automatiquement mis à jour à chaque modification du code ou des fichiers de configuration. En mode production, il n'est généré qu'une seule fois et les modifications ne sont pas vérifiées pour maximiser les performances.
Nous chargeons les fichiers de configuration à l'aide de addConfig()
:
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
Si nous voulons ajouter plusieurs fichiers de configuration, nous pouvons appeler la fonction addConfig()
plusieurs fois.
$configDir = $this->rootDir . '/config';
$this->configurator->addConfig($configDir . '/common.neon');
$this->configurator->addConfig($configDir . '/services.neon');
if (PHP_SAPI === 'cli') {
$this->configurator->addConfig($configDir . '/cli.php');
}
Le nom cli.php
n'est pas une faute de frappe ; la configuration peut également être écrite dans un fichier PHP
qui la retourne sous forme de tableau.
Nous pouvons également ajouter d'autres fichiers de configuration dans la section includes
.
Si des éléments avec les mêmes clés apparaissent dans les fichiers de configuration, ils seront écrasés ou, dans le cas
des tableaux, fusionnés. Le fichier
inclus ultérieurement a une priorité plus élevée que le précédent. Le fichier dans lequel la section includes
est listée a une priorité plus élevée que les fichiers qui y sont inclus.
Paramètres Statiques
Les paramètres utilisés dans les fichiers de configuration peuvent être définis dans la section parameters
et
également transmis (ou écrasés) via la méthode addStaticParameters()
(qui a un alias
addParameters()
). Il est important de noter que différentes valeurs de paramètres entraîneront la génération de
conteneurs DI supplémentaires, c'est-à-dire de classes supplémentaires.
$this->configurator->addStaticParameters([
'projectId' => 23,
]);
Le paramètre projectId
peut être référencé dans la configuration en utilisant la notation habituelle
%projectId%
.
Paramètres Dynamiques
Nous pouvons également ajouter des paramètres dynamiques au conteneur, dont les différentes valeurs, contrairement aux paramètres statiques, ne provoquent pas la génération de nouveaux conteneurs DI.
$this->configurator->addDynamicParameters([
'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
Nous pouvons ainsi facilement ajouter, par exemple, des variables d'environnement, qui peuvent ensuite être référencées
dans la configuration en utilisant la notation %env.variable%
.
$this->configurator->addDynamicParameters([
'env' => getenv(),
]);
Paramètres par Défaut
Dans les fichiers de configuration, vous pouvez utiliser ces paramètres statiques :
%appDir%
est le chemin absolu vers le répertoire contenant le fichierBootstrap.php
%wwwDir%
est le chemin absolu vers le répertoire contenant le fichier d'entréeindex.php
%tempDir%
est le chemin absolu vers le répertoire des fichiers temporaires%vendorDir%
est le chemin absolu vers le répertoire où Composer installe les bibliothèques%rootDir%
est le chemin absolu vers le répertoire racine du projet%debugMode%
indique si l'application est en mode débogage%consoleMode%
indique si la requête provient de la ligne de commande
Services Importés
Maintenant, allons plus en profondeur. Bien que le but du conteneur DI soit de créer des objets, il peut exceptionnellement
être nécessaire d'insérer un objet existant dans le conteneur. Nous le faisons en définissant le service avec l'indicateur
imported: true
.
services:
myservice:
type: App\Model\MyCustomService
imported: true
Et dans le bootstrap, nous insérons l'objet dans le conteneur :
$this->configurator->addServices([
'myservice' => new App\Model\MyCustomService('foobar'),
]);
Environnements Différents
N'hésitez pas à modifier la classe Bootstrap selon vos besoins. Vous pouvez ajouter des paramètres à la méthode
bootWebApplication()
pour distinguer les projets web. Ou nous pouvons ajouter d'autres méthodes, par exemple
bootTestEnvironment()
, qui initialise l'environnement pour les tests unitaires, bootConsoleApplication()
pour les scripts appelés depuis la ligne de commande, etc.
public function bootTestEnvironment(): Nette\DI\Container
{
Tester\Environment::setup(); // initialisation de Nette Tester
$this->setupContainer();
return $this->configurator->createContainer();
}
public function bootConsoleApplication(): Nette\DI\Container
{
$this->configurator->setDebugMode(false);
$this->initializeEnvironment();
$this->setupContainer();
return $this->configurator->createContainer();
}