Bootstrap

Bootstrap est le code de démarrage qui initialise l'environnement, crée un conteneur d'injection de dépendances (DI) et démarre l'application. Nous en discuterons :

  • comment configurer votre application à l'aide de fichiers NEON
  • comment gérer les modes production et développement
  • comment créer le conteneur DI

Les applications, qu'elles soient basées sur le Web ou sur des scripts en ligne de commande, commencent par une certaine forme d'initialisation de l'environnement. Dans les temps anciens, il pouvait s'agir d'un fichier nommé eg include.inc.php qui s'en chargeait, et qui était inclus dans le fichier initial. Dans les applications Nette modernes, il a été remplacé par la classe Bootstrap, qui, en tant que partie intégrante de l'application, se trouve dans le fichier app/Bootstrap.php. Il peut ressembler à ceci par exemple :

use Nette\Bootstrap\Configurator;

class Bootstrap
{
	public static function boot(): Configurator
	{
		$appDir = dirname(__DIR__);
		$configurator = new Configurator;
		//$configurator->setDebugMode('secret@23.75.345.200');
		$configurator->enableTracy($appDir . '/log');
		$configurator->setTempDirectory($appDir . '/temp');
		$configurator->createRobotLoader()
			->addDirectory(__DIR__)
			->register();
		$configurator->addConfig($appDir . '/config/common.neon');
		return $configurator;
	}
}

index.php

Dans le cas des applications web, le fichier initial est index.php, qui se trouve dans le répertoire public www/. Il laisse la classe Bootstrap pour initialiser l'environnement et retourne la classe $configurator qui crée le conteneur DI. Ensuite, il obtient le service Application, qui exécute l'application web :

// initialisation de l'environnement + obtention de l'objet Configurateur
$configurator = App\Bootstrap::boot();
// créer un conteneur DI
$container = $configurator->createContainer();
// Le conteneur DI crée un objet Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
// Démarrage de l'application Nette
$application->run();

Comme vous pouvez le constater, la classe Nette\Bootstrap\Configurator, que nous allons maintenant présenter plus en détail, aide à configurer l'environnement et à créer un conteneur d'injection de dépendances (DI).

Mode développement et mode production

Nette distingue deux modes de base dans lesquels une requête est exécutée : développement et production. Le mode développement est axé sur le confort maximal du programmeur, Tracy est affiché, le cache est automatiquement mis à jour lors de la modification des modèles ou de la configuration du conteneur DI, etc. Le mode production est axé sur les performances, Tracy ne consigne que les erreurs et les modifications des templates et autres fichiers ne sont pas vérifiées.

La sélection du mode se fait par autodétection, il n'est donc généralement pas nécessaire de configurer ou de changer quoi que ce soit manuellement. Le mode est développement si l'application est exécutée sur l'hôte local (c'est-à-dire l'adresse IP 127.0.0.1 ou ::1) et qu'aucun proxy n'est présent (c'est-à-dire son en-tête HTTP). Sinon, elle s'exécute en mode production.

Si vous souhaitez activer le mode développement dans d'autres cas, par exemple pour les programmeurs accédant depuis une adresse IP spécifique, vous pouvez utiliser setDebugMode():

$configurator->setDebugMode('23.75.345.200'); // une ou plusieurs adresses IP

Nous recommandons vivement de combiner une adresse IP avec un cookie. Nous stockerons un jeton secret dans le cookie nette-debug, par exemple secret1234, et le mode de développement sera activé pour les programmeurs avec cette combinaison d'IP et de cookie.

$configurator->setDebugMode('secret1234@23.75.345.200');

Nous pouvons également désactiver complètement le mode de développement, même pour localhost :

$configurator->setDebugMode(false);

Notez que la valeur true active le mode développeur par défaut, ce qui ne devrait jamais arriver sur un serveur de production.

Outil de débogage Tracy

Pour faciliter le débogage, nous allons activer l'excellent outil Tracy. En mode développeur, il visualise les erreurs et en mode production, il enregistre les erreurs dans le répertoire spécifié :

$configurator->enableTracy($appDir . '/log');

Fichiers temporaires

Nette utilise le cache pour le conteneur DI, RobotLoader, les modèles, etc. Il est donc nécessaire de définir le chemin d'accès au répertoire où le cache sera stocké :

$configurator->setTempDirectory($appDir . '/temp');

Sous Linux ou macOS, définissez les droits d'écriture pour les répertoires log/ et temp/.

RobotLoader

En général, nous voulons charger automatiquement les classes à l'aide de RobotLoader, nous devons donc le lancer et le laisser charger les classes du répertoire où se trouve Bootstrap.php (c'est-à-dire __DIR__) et de tous ses sous-répertoires :

$configurator->createRobotLoader()
	->addDirectory(__DIR__)
	->register();

Une autre solution consiste à utiliser uniquement le chargement automatique de Composer PSR-4.

Fuseau horaire

Le configurateur vous permet de spécifier un fuseau horaire pour votre application.

$configurator->setTimeZone('Europe/Prague');

Configuration du conteneur DI

Une partie du processus de démarrage est la création d'un conteneur DI, c'est-à-dire une fabrique 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 un répertoire de cache. La fabrique produit les objets clés de l'application et les fichiers de configuration lui indiquent comment les créer et les configurer, et ainsi nous influençons le comportement de l'application entière.

Les fichiers de configuration sont généralement écrits au format NEON. Vous pouvez lire ce qui peut être configuré ici.

En mode développement, le conteneur est automatiquement mis à jour chaque fois que vous modifiez le code ou les fichiers de configuration. En mode production, il n'est généré qu'une seule fois et les modifications de fichiers ne sont pas vérifiées afin de maximiser les performances.

Les fichiers de configuration sont chargés à l'aide de addConfig():

$configurator->addConfig($appDir . '/config/common.neon');

La méthode addConfig() peut être appelée plusieurs fois pour ajouter plusieurs fichiers.

$configurator->addConfig($appDir . '/config/common.neon');
$configurator->addConfig($appDir . '/config/services.neon');
if (PHP_SAPI === 'cli') {
	$configurator->addConfig($appDir . '/config/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 renvoie sous forme de tableau.

Alternativement, nous pouvons utiliser la sectionincludes pour charger plus de fichiers de configuration.

Si des éléments avec les mêmes clés apparaissent dans les fichiers de configuration, ils seront écrasés ou fusionnés dans le cas de tableaux. Le dernier fichier inclus a une priorité plus élevée que le précédent. Le fichier dans lequel figure la section includes 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) par la méthode addStaticParameters() (qui a un alias addParameters()). Il est important que les différentes valeurs des paramètres entraînent la génération de conteneurs DI supplémentaires, c'est-à-dire de classes supplémentaires.

$configurator->addStaticParameters([
	'projectId' => 23,
]);

Dans les fichiers de configuration, nous pouvons écrire la notation habituelle %projectId% pour accéder au paramètre nommé projectId.

Paramètres dynamiques

Nous pouvons également ajouter des paramètres dynamiques au conteneur, leurs différentes valeurs, contrairement aux paramètres statiques, ne provoqueront pas la génération de nouveaux conteneurs DI.

$configurator->addDynamicParameters([
	'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);

Les variables d'environnement peuvent être facilement mises à disposition à l'aide de paramètres dynamiques. Nous pouvons y accéder via %env.variable% dans les fichiers de configuration.

$configurator->addDynamicParameters([
	'env' => getenv(),
]);

Paramètres par défaut

Vous pouvez utiliser les paramètres statiques suivants dans les fichiers de configuration :

  • %appDir% est le chemin absolu vers le répertoire du fichier Bootstrap.php
  • %wwwDir% est le chemin absolu vers le répertoire contenant le fichier d'entrée index.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
  • %debugMode% indique si l'application est en mode débogage
  • %consoleMode% indique si la demande provient de la ligne de commande

Services importés

Nous allons maintenant plus loin. Bien que le but d'un 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'attribut imported: true.

services:
	myservice:
		type: App\Model\MyCustomService
		imported: true

Créez une nouvelle instance et insérez-la dans bootstrap :

$configurator->addServices([
	'myservice' => new App\Model\MyCustomService('foobar'),
]);

Différents environnements

N'hésitez pas à personnaliser la classe Bootstrap en fonction de vos besoins. Vous pouvez ajouter des paramètres à la méthode boot() pour différencier les projets Web, ou ajouter d'autres méthodes, comme bootForTests(), qui initialise l'environnement pour les tests unitaires, bootForCli() pour les scripts appelés depuis la ligne de commande, etc.

public static function bootForTests(): Configurator
{
	$configurator = self::boot();
	Tester\Environment::setup(); // Initialisation du testeur de nappe
	return $configurator;
}
version: 4.0