Nette Documentation Preview

syntax
Bootstrap
*********

<div class=perex>

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

</div>


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 :

```php
use Nette\Bootstrap\Configurator;

class Bootstrap
{
	private Configurator $configurator;
	private string $rootDir;

	public function __construct()
	{
		$this->rootDir = dirname(__DIR__);
		// Le configurateur est chargé de configurer l'environnement et les services de l'application.
		$this->configurator = new Configurator;
		// Définir le répertoire pour les fichiers temporaires générés par Nette (par exemple, les modèles 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 outil de débogage "couteau suisse".
		$this->configurator->enableTracy($this->rootDir . '/log');

		// RobotLoader: charge automatiquement toutes les classes dans le répertoire donné
		$this->configurator->createRobotLoader()
			->addDirectory(__DIR__)
			->register();
	}

	private function setupContainer(): void
	{
		// Chargement des fichiers de configuration
		$this->configurator->addConfig($this->rootDir . '/config/common.neon');
	}
}
```


index.php .[#toc-index-php]
===========================

Le fichier initial des applications web est `index.php`, situé dans le répertoire public `www/`. Il utilise la classe `Bootstrap` pour initialiser l'environnement et créer un conteneur DI. Ensuite, il obtient le service `Application` du conteneur, ce qui lance l'application web :

```php
$bootstrap = new App\Bootstrap;
// Initialiser l'environnement + créer un conteneur DI
$container = $bootstrap->bootWebApplication();
// Le conteneur DI crée un objet Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
// Démarrer l'application Nette et traiter la demande entrante
$application->run();
```

Comme vous pouvez le constater, la classe [api: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 .[#toc-development-vs-production-mode]
============================================================================

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()`:

```php
$this->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.

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

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

```php
$this->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 .[#toc-debugging-tool-tracy]
====================================================

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

```php
$this->configurator->enableTracy($this->rootDir . '/log');
```


Fichiers temporaires .[#toc-temporary-files]
============================================

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é :

```php
$this->configurator->setTempDirectory($this->rootDir . '/temp');
```

Sous Linux ou macOS, définissez les [droits d'écriture |nette:troubleshooting#Setting directory permissions] pour les répertoires `log/` et `temp/`.


RobotLoader .[#toc-robotloader]
===============================

En général, nous voulons charger automatiquement les classes à l'aide de [RobotLoader |robot-loader:], 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 :

```php
$this->configurator->createRobotLoader()
	->addDirectory(__DIR__)
	->register();
```

Une autre solution consiste à utiliser uniquement le chargement automatique de [Composer |best-practices:composer] PSR-4.


Fuseau horaire .[#toc-timezone]
===============================

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

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


Configuration du conteneur DI .[#toc-di-container-configuration]
================================================================

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 |neon:format]. Vous pouvez lire [ce qui peut être configuré ici |nette:configuring].

.[tip]
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()`:

```php
$this->configurator->addConfig($this->rootDir . '/config/common.neon');
```

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

```php
$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 renvoie sous forme de tableau.

Alternativement, nous pouvons utiliser la [section`includes`  |dependency-injection:configuration#including files] 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 |dependency-injection:configuration#Merging] 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 .[#toc-static-parameters]
----------------------------------------------

Les paramètres utilisés dans les fichiers de configuration peuvent être définis [dans la section `parameters` |dependency-injection:configuration#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.

```php
$this->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 .[#toc-dynamic-parameters]
------------------------------------------------

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.

```php
$this->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.

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


Paramètres par défaut .[#toc-default-parameters]
------------------------------------------------

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
- `%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 demande provient de la ligne de commande


Services importés .[#toc-imported-services]
-------------------------------------------

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`.

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

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

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


Différents environnements .[#toc-different-environments]
========================================================

N'hésitez pas à personnaliser la classe `Bootstrap` en fonction de vos besoins. Vous pouvez ajouter des paramètres à la méthode `bootWebApplication()` pour différencier les projets web. Vous pouvez également ajouter d'autres méthodes, telles que `bootTestEnvironment()` pour initialiser l'environnement des tests unitaires, `bootConsoleApplication()` pour les scripts appelés à partir de la ligne de commande, etc.

```php
public function bootTestEnvironment(): Nette\DI\Container
{
	Tester\Environment::setup(); // Initialisation du testeur Nette
	$this->setupContainer();
	return $this->configurator->createContainer();
}

public function bootConsoleApplication(): Nette\DI\Container
{
	$this->configurator->setDebugMode(false);
	$this->initializeEnvironment();
	$this->setupContainer();
	return $this->configurator->createContainer();
}
```

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
{
	private Configurator $configurator;
	private string $rootDir;

	public function __construct()
	{
		$this->rootDir = dirname(__DIR__);
		// Le configurateur est chargé de configurer l'environnement et les services de l'application.
		$this->configurator = new Configurator;
		// Définir le répertoire pour les fichiers temporaires générés par Nette (par exemple, les modèles 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 outil de débogage "couteau suisse".
		$this->configurator->enableTracy($this->rootDir . '/log');

		// RobotLoader: charge automatiquement toutes les classes dans le répertoire donné
		$this->configurator->createRobotLoader()
			->addDirectory(__DIR__)
			->register();
	}

	private function setupContainer(): void
	{
		// Chargement des fichiers de configuration
		$this->configurator->addConfig($this->rootDir . '/config/common.neon');
	}
}

index.php

Le fichier initial des applications web est index.php, situé dans le répertoire public www/. Il utilise la classe Bootstrap pour initialiser l'environnement et créer un conteneur DI. Ensuite, il obtient le service Application du conteneur, ce qui lance l'application web :

$bootstrap = new App\Bootstrap;
// Initialiser l'environnement + créer un conteneur DI
$container = $bootstrap->bootWebApplication();
// Le conteneur DI crée un objet Nette\Application\Application
$application = $container->getByType(Nette\Application\Application::class);
// Démarrer l'application Nette et traiter la demande entrante
$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():

$this->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.

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

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

$this->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é :

$this->configurator->enableTracy($this->rootDir . '/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é :

$this->configurator->setTempDirectory($this->rootDir . '/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 :

$this->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.

$this->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():

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

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

$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 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.

$this->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.

$this->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.

$this->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
  • %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 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 :

$this->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 bootWebApplication() pour différencier les projets web. Vous pouvez également ajouter d'autres méthodes, telles que bootTestEnvironment() pour initialiser l'environnement des tests unitaires, bootConsoleApplication() pour les scripts appelés à partir de la ligne de commande, etc.

public function bootTestEnvironment(): Nette\DI\Container
{
	Tester\Environment::setup(); // Initialisation du testeur Nette
	$this->setupContainer();
	return $this->configurator->createContainer();
}

public function bootConsoleApplication(): Nette\DI\Container
{
	$this->configurator->setDebugMode(false);
	$this->initializeEnvironment();
	$this->setupContainer();
	return $this->configurator->createContainer();
}