Nette Documentation Preview

syntax
Définitions des services
************************

.[perex]
La configuration est l'endroit où nous plaçons les définitions des services personnalisés. Ceci est fait dans la section `services`.

Par exemple, voici comment nous créons un service nommé `database`, qui sera une instance de la classe `PDO`:

```neon
services:
	database: PDO('sqlite::memory:')
```

Le nommage des services est utilisé pour nous permettre de les [référencer |#Referencing Services]. Si un service n'est pas référencé, il n'est pas nécessaire de le nommer. Nous utilisons donc simplement une puce au lieu d'un nom :

```neon
services:
	- PDO('sqlite::memory:') # service anonyme
```

Une entrée d'une ligne peut être décomposée en plusieurs lignes pour permettre l'ajout de clés supplémentaires, telles que [setup |#setup]. L'alias de la clé `create:` est `factory:`.

```neon
services:
	database:
		create: PDO('sqlite::memory:')
		setup: ...
```

Nous récupérons ensuite le service dans le conteneur DI en utilisant la méthode `getService()` par nom, ou mieux encore, la méthode `getByType()` par type :

```php
$database = $container->getService('database');
$database = $container->getByType(PDO::class);
```


Création d'un service .[#toc-creating-a-service]
================================================

Le plus souvent, nous créons un service en créant simplement une instance d'une classe :

```neon
services:
	database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)
```

Ce qui va générer une méthode de fabrique dans le [conteneur DI |container]:

```php
public function createServiceDatabase(): PDO
{
	return new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'secret');
}
```

Alternativement, une clé `arguments` peut être utilisée pour passer des [arguments |#Arguments]:

```neon
services:
	database:
		create: PDO
		arguments: ['mysql:host=127.0.0.1;dbname=test', root, secret]
```

Une méthode statique peut également créer un service :

```neon
services:
	database: My\Database::create(root, secret)
```

Correspond au code PHP :

```php
public function createServiceDatabase(): PDO
{
	return My\Database::create('root', 'secret');
}
```

Une méthode statique `My\Database::create()` est supposée avoir une valeur de retour définie que le conteneur DI doit connaître. S'il ne l'a pas, nous écrivons le type dans la configuration :

```neon
services:
	database:
		create: My\Database::create(root, secret)
		type: PDO
```

Nette DI vous donne des facilités d'expression extrêmement puissantes pour écrire presque n'importe quoi. Par exemple, pour [faire référence |#Referencing Services] à un autre service et appeler sa méthode. Pour simplifier, on utilise `::` au lieu de `->`.

```neon
services:
	routerFactory: App\Router\Factory
	router: @routerFactory::create()
```

Correspond au code PHP :

```php
public function createServiceRouterFactory(): App\Router\Factory
{
	return new App\Router\Factory;
}

public function createServiceRouter(): Router
{
	return $this->getService('routerFactory')->create();
}
```

Les appels de méthode peuvent être enchaînés comme en PHP :

```neon
services:
	foo: FooFactory::build()::get()
```

Correspond au code PHP :

```php
public function createServiceFoo()
{
	return FooFactory::build()->get();
}
```


Arguments .[#toc-arguments]
===========================

Les paramètres nommés peuvent également être utilisés pour transmettre des arguments :

```neon
services:
	database: PDO(
		mysql:host=127.0.0.1;dbname=test' # positionnel
		username: root                    # nommé
		password: secret                  # nommé
	)
```

L'utilisation de virgules est facultative lorsque les arguments sont répartis sur plusieurs lignes.

Bien entendu, nous pouvons également utiliser [d'autres services |#Referencing Services] ou [paramètres |configuration#parameters] comme arguments :

```neon
services:
	- Foo(@anotherService, %appDir%)
```

Correspond au code PHP :

```php
public function createService01(): Foo
{
	return new Foo($this->getService('anotherService'), '...');
}
```

Si le premier argument est [autodirigé |autowiring] et que vous souhaitez spécifier le second, omettez le premier avec `_` character, for example `Foo(_, %appDir%)`. Ou mieux encore, passez uniquement le second argument comme paramètre nommé, par exemple `Foo(path: %appDir%)`.

Nette DI et le format NEON vous offrent des possibilités d'expression extrêmement puissantes pour écrire presque tout. Ainsi, un argument peut être un objet nouvellement créé, vous pouvez appeler des méthodes statiques, des méthodes d'autres services, ou même des fonctions globales en utilisant une notation spéciale :

```neon
services:
	analyser: My\Analyser(
		FilesystemIterator(%appDir%)        # créer un objet
		DateTime::createFromFormat('Y-m-d') # appelle la méthode statique
		@anotherService                     # passage d'un autre service
		@http.request::getRemoteAddress()   # appel d'une autre méthode de service
		::getenv(NetteMode)                 # appel d'une fonction globale
	)
```

Correspond au code PHP :

```php
public function createServiceAnalyser(): My\Analyser
{
	return new My\Analyser(
		new FilesystemIterator('...'),
		DateTime::createFromFormat('Y-m-d'),
		$this->getService('anotherService'),
		$this->getService('http.request')->getRemoteAddress(),
		getenv('NetteMode')
	);
}
```


Fonctions spéciales .[#toc-special-functions]
---------------------------------------------

Vous pouvez également utiliser des fonctions spéciales dans les arguments pour exprimer ou nier des valeurs :

- `not(%arg%)` négation
- `bool(%arg%)` Conversion sans perte en bool
- `int(%arg%)` Conversion sans perte en int
- `float(%arg%)` conversion sans perte en float
- `string(%arg%)` Moulage sans perte vers string

```neon
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)
```

La réécriture sans perte diffère de la réécriture PHP normale, par exemple en utilisant `(int)`, car elle lève une exception pour les valeurs non numériques.

Plusieurs services peuvent être passés en argument. Un tableau de tous les services d'un type particulier (c'est-à-dire une classe ou une interface) est créé par la fonction `typed()`. La fonction omettra les services dont le câblage automatique est désactivé, et plusieurs types séparés par une virgule peuvent être spécifiés.

```neon
services:
	- BarsDependent( typed(Bar) )
```

Vous pouvez également passer un tableau de services automatiquement en utilisant le [câblage automatique |autowiring#Collection of Services].

Un tableau de tous les services avec une certaine [étiquette |#tags] est créé par la fonction `tagged()`. Plusieurs balises séparées par une virgule peuvent être spécifiées.

```neon
services:
	- LoggersDependent( tagged(logger) )
```


Services de référencement .[#toc-referencing-services]
======================================================

Les services individuels sont référencés à l'aide du caractère `@` and name, so for example `@database`:

```neon
services:
	- create: Foo(@database)
	  setup:
			- setCacheStorage(@cache.storage)
```

Correspond au code PHP :

```php
public function createService01(): Foo
{
	$service = new Foo($this->getService('database'));
	$service->setCacheStorage($this->getService('cache.storage'));
	return $service;
}
```

Même les services anonymes peuvent être référencés à l'aide d'un callback, il suffit de spécifier leur type (classe ou interface) au lieu de leur nom. Cependant, cela n'est généralement pas nécessaire en raison du [câblage automatique |autowiring].

```neon
services:
	- create: Foo(@Nette\Database\Connection)  # ou @\PDO
	  setup:
			- setCacheStorage(@cache.storage)
```


Configuration .[#toc-setup]
===========================

Dans la section "setup", nous listons les méthodes à appeler lors de la création du service :

```neon
services:
	database:
		create: PDO(%dsn%, %user%, %password%)
		setup:
			- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
```

Correspond au code PHP :

```php
public function createServiceDatabase(): PDO
{
	$service = new PDO('...', '...', '...');
	$service->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	return $service;
}
```

Les propriétés peuvent également être définies. L'ajout d'un élément à un tableau est également supporté, et doit être écrit entre guillemets pour ne pas entrer en conflit avec la syntaxe NEON :


```neon
services:
	foo:
		create: Foo
		setup:
			- $value = 123
			- '$onClick[]' = [@bar, clickHandler]
```

Correspond au code PHP :

```php
public function createServiceFoo(): Foo
{
	$service = new Foo;
	$service->value = 123;
	$service->onClick[] = [$this->getService('bar'), 'clickHandler'];
	return $service;
}
```

Cependant, les méthodes statiques ou les méthodes d'autres services peuvent également être appelées dans la configuration. Nous leur passons le service réel en tant que `@self`:


```neon
services:
	foo:
		create: Foo
		setup:
			- My\Helpers::initializeFoo(@self)
			- @anotherService::setFoo(@self)
```

Correspond au code PHP :

```php
public function createServiceFoo(): Foo
{
	$service = new Foo;
	My\Helpers::initializeFoo($service);
	$this->getService('anotherService')->setFoo($service);
	return $service;
}
```


Câblage automatique .[#toc-autowiring]
======================================

La clé autowired peut être utilisée pour exclure un service de l'autowiring ou pour influencer son comportement. Voir le [chapitre sur le câblage automatique |autowiring] pour plus d'informations.

```neon
services:
	foo:
		create: Foo
		autowired: false # foo est retiré de l'autowiring
```


Tags .[#toc-tags]
=================

Des informations sur les utilisateurs peuvent être ajoutées aux services individuels sous la forme de balises :

```neon
services:
	foo:
		create: Foo
		tags:
			- cached
```

Les étiquettes peuvent également avoir une valeur :

```neon
services:
	foo:
		create: Foo
		tags:
			logger: monolog.logger.event
```

Un tableau de services avec certaines balises peut être passé comme argument en utilisant la fonction `tagged()`. Plusieurs balises séparées par une virgule peuvent également être spécifiées.

```neon
services:
	- LoggersDependent( tagged(logger) )
```

Les noms des services peuvent être obtenus du conteneur DI à l'aide de la méthode `findByTag()`:

```php
$names = $container->findByTag('logger');
// $names est un tableau contenant le nom du service et la valeur du tag
// c'est-à-dire ['foo' => 'monolog.logger.event', ...]
```


Mode d'injection .[#toc-inject-mode]
====================================

L'indicateur `inject: true` est utilisé pour activer le passage des dépendances via des variables publiques avec l'annotation [inject |best-practices:inject-method-attribute#Inject Attributes] et les méthodes [inject*() |best-practices:inject-method-attribute#inject Methods].

```neon
services:
	articles:
		create: App\Model\Articles
		inject: true
```

Par défaut, `inject` n'est activé que pour les présentateurs.


Modification des services .[#toc-modification-of-services]
==========================================================

Il existe un certain nombre de services dans le conteneur DI qui ont été ajoutés par l'intégration ou [votre extension |#di-extensions]. Les définitions de ces services peuvent être modifiées dans la configuration. Par exemple, pour le service `application.application`, qui est par défaut un objet `Nette\Application\Application`, nous pouvons changer la classe :

```neon
services:
	application.application:
		create: MyApplication
		alteration: true
```

Le drapeau `alteration` est informatif et indique que nous ne faisons que modifier un service existant.

Nous pouvons également ajouter un service :

```neon
services:
	application.application:
		create: MyApplication
		alteration: true
		setup:
			- '$onStartup[]' = [@resource, init]
```

Lorsque nous réécrivons un service, nous pouvons vouloir supprimer les arguments, les éléments de configuration ou les balises d'origine, ce à quoi sert `reset`:

```neon
services:
	application.application:
		create: MyApplication
		alteration: true
		reset:
			- arguments
			- setup
			- tags
```

Un service ajouté par extension peut également être retiré du conteneur :

```neon
services:
	cache.journal: false
```

Définitions des services

La configuration est l'endroit où nous plaçons les définitions des services personnalisés. Ceci est fait dans la section services.

Par exemple, voici comment nous créons un service nommé database, qui sera une instance de la classe PDO:

services:
	database: PDO('sqlite::memory:')

Le nommage des services est utilisé pour nous permettre de les référencer. Si un service n'est pas référencé, il n'est pas nécessaire de le nommer. Nous utilisons donc simplement une puce au lieu d'un nom :

services:
	- PDO('sqlite::memory:') # service anonyme

Une entrée d'une ligne peut être décomposée en plusieurs lignes pour permettre l'ajout de clés supplémentaires, telles que setup. L'alias de la clé create: est factory:.

services:
	database:
		create: PDO('sqlite::memory:')
		setup: ...

Nous récupérons ensuite le service dans le conteneur DI en utilisant la méthode getService() par nom, ou mieux encore, la méthode getByType() par type :

$database = $container->getService('database');
$database = $container->getByType(PDO::class);

Création d'un service

Le plus souvent, nous créons un service en créant simplement une instance d'une classe :

services:
	database: PDO('mysql:host=127.0.0.1;dbname=test', root, secret)

Ce qui va générer une méthode de fabrique dans le conteneur DI:

public function createServiceDatabase(): PDO
{
	return new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'secret');
}

Alternativement, une clé arguments peut être utilisée pour passer des arguments:

services:
	database:
		create: PDO
		arguments: ['mysql:host=127.0.0.1;dbname=test', root, secret]

Une méthode statique peut également créer un service :

services:
	database: My\Database::create(root, secret)

Correspond au code PHP :

public function createServiceDatabase(): PDO
{
	return My\Database::create('root', 'secret');
}

Une méthode statique My\Database::create() est supposée avoir une valeur de retour définie que le conteneur DI doit connaître. S'il ne l'a pas, nous écrivons le type dans la configuration :

services:
	database:
		create: My\Database::create(root, secret)
		type: PDO

Nette DI vous donne des facilités d'expression extrêmement puissantes pour écrire presque n'importe quoi. Par exemple, pour faire référence à un autre service et appeler sa méthode. Pour simplifier, on utilise :: au lieu de ->.

services:
	routerFactory: App\Router\Factory
	router: @routerFactory::create()

Correspond au code PHP :

public function createServiceRouterFactory(): App\Router\Factory
{
	return new App\Router\Factory;
}

public function createServiceRouter(): Router
{
	return $this->getService('routerFactory')->create();
}

Les appels de méthode peuvent être enchaînés comme en PHP :

services:
	foo: FooFactory::build()::get()

Correspond au code PHP :

public function createServiceFoo()
{
	return FooFactory::build()->get();
}

Arguments

Les paramètres nommés peuvent également être utilisés pour transmettre des arguments :

services:
	database: PDO(
		mysql:host=127.0.0.1;dbname=test' # positionnel
		username: root                    # nommé
		password: secret                  # nommé
	)

L'utilisation de virgules est facultative lorsque les arguments sont répartis sur plusieurs lignes.

Bien entendu, nous pouvons également utiliser d'autres services ou paramètres comme arguments :

services:
	- Foo(@anotherService, %appDir%)

Correspond au code PHP :

public function createService01(): Foo
{
	return new Foo($this->getService('anotherService'), '...');
}

Si le premier argument est autodirigé et que vous souhaitez spécifier le second, omettez le premier avec _ character, for example Foo(_, %appDir%). Ou mieux encore, passez uniquement le second argument comme paramètre nommé, par exemple Foo(path: %appDir%).

Nette DI et le format NEON vous offrent des possibilités d'expression extrêmement puissantes pour écrire presque tout. Ainsi, un argument peut être un objet nouvellement créé, vous pouvez appeler des méthodes statiques, des méthodes d'autres services, ou même des fonctions globales en utilisant une notation spéciale :

services:
	analyser: My\Analyser(
		FilesystemIterator(%appDir%)        # créer un objet
		DateTime::createFromFormat('Y-m-d') # appelle la méthode statique
		@anotherService                     # passage d'un autre service
		@http.request::getRemoteAddress()   # appel d'une autre méthode de service
		::getenv(NetteMode)                 # appel d'une fonction globale
	)

Correspond au code PHP :

public function createServiceAnalyser(): My\Analyser
{
	return new My\Analyser(
		new FilesystemIterator('...'),
		DateTime::createFromFormat('Y-m-d'),
		$this->getService('anotherService'),
		$this->getService('http.request')->getRemoteAddress(),
		getenv('NetteMode')
	);
}

Fonctions spéciales

Vous pouvez également utiliser des fonctions spéciales dans les arguments pour exprimer ou nier des valeurs :

  • not(%arg%) négation
  • bool(%arg%) Conversion sans perte en bool
  • int(%arg%) Conversion sans perte en int
  • float(%arg%) conversion sans perte en float
  • string(%arg%) Moulage sans perte vers string
services:
	- Foo(
		id: int(::getenv('ProjectId'))
		productionMode: not(%debugMode%)
	)

La réécriture sans perte diffère de la réécriture PHP normale, par exemple en utilisant (int), car elle lève une exception pour les valeurs non numériques.

Plusieurs services peuvent être passés en argument. Un tableau de tous les services d'un type particulier (c'est-à-dire une classe ou une interface) est créé par la fonction typed(). La fonction omettra les services dont le câblage automatique est désactivé, et plusieurs types séparés par une virgule peuvent être spécifiés.

services:
	- BarsDependent( typed(Bar) )

Vous pouvez également passer un tableau de services automatiquement en utilisant le câblage automatique.

Un tableau de tous les services avec une certaine étiquette est créé par la fonction tagged(). Plusieurs balises séparées par une virgule peuvent être spécifiées.

services:
	- LoggersDependent( tagged(logger) )

Services de référencement

Les services individuels sont référencés à l'aide du caractère @ and name, so for example @database:

services:
	- create: Foo(@database)
	  setup:
			- setCacheStorage(@cache.storage)

Correspond au code PHP :

public function createService01(): Foo
{
	$service = new Foo($this->getService('database'));
	$service->setCacheStorage($this->getService('cache.storage'));
	return $service;
}

Même les services anonymes peuvent être référencés à l'aide d'un callback, il suffit de spécifier leur type (classe ou interface) au lieu de leur nom. Cependant, cela n'est généralement pas nécessaire en raison du câblage automatique.

services:
	- create: Foo(@Nette\Database\Connection)  # ou @\PDO
	  setup:
			- setCacheStorage(@cache.storage)

Configuration

Dans la section „setup“, nous listons les méthodes à appeler lors de la création du service :

services:
	database:
		create: PDO(%dsn%, %user%, %password%)
		setup:
			- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)

Correspond au code PHP :

public function createServiceDatabase(): PDO
{
	$service = new PDO('...', '...', '...');
	$service->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
	return $service;
}

Les propriétés peuvent également être définies. L'ajout d'un élément à un tableau est également supporté, et doit être écrit entre guillemets pour ne pas entrer en conflit avec la syntaxe NEON :

services:
	foo:
		create: Foo
		setup:
			- $value = 123
			- '$onClick[]' = [@bar, clickHandler]

Correspond au code PHP :

public function createServiceFoo(): Foo
{
	$service = new Foo;
	$service->value = 123;
	$service->onClick[] = [$this->getService('bar'), 'clickHandler'];
	return $service;
}

Cependant, les méthodes statiques ou les méthodes d'autres services peuvent également être appelées dans la configuration. Nous leur passons le service réel en tant que @self:

services:
	foo:
		create: Foo
		setup:
			- My\Helpers::initializeFoo(@self)
			- @anotherService::setFoo(@self)

Correspond au code PHP :

public function createServiceFoo(): Foo
{
	$service = new Foo;
	My\Helpers::initializeFoo($service);
	$this->getService('anotherService')->setFoo($service);
	return $service;
}

Câblage automatique

La clé autowired peut être utilisée pour exclure un service de l'autowiring ou pour influencer son comportement. Voir le chapitre sur le câblage automatique pour plus d'informations.

services:
	foo:
		create: Foo
		autowired: false # foo est retiré de l'autowiring

Tags

Des informations sur les utilisateurs peuvent être ajoutées aux services individuels sous la forme de balises :

services:
	foo:
		create: Foo
		tags:
			- cached

Les étiquettes peuvent également avoir une valeur :

services:
	foo:
		create: Foo
		tags:
			logger: monolog.logger.event

Un tableau de services avec certaines balises peut être passé comme argument en utilisant la fonction tagged(). Plusieurs balises séparées par une virgule peuvent également être spécifiées.

services:
	- LoggersDependent( tagged(logger) )

Les noms des services peuvent être obtenus du conteneur DI à l'aide de la méthode findByTag():

$names = $container->findByTag('logger');
// $names est un tableau contenant le nom du service et la valeur du tag
// c'est-à-dire ['foo' => 'monolog.logger.event', ...]

Mode d'injection

L'indicateur inject: true est utilisé pour activer le passage des dépendances via des variables publiques avec l'annotation inject et les méthodes inject*().

services:
	articles:
		create: App\Model\Articles
		inject: true

Par défaut, inject n'est activé que pour les présentateurs.

Modification des services

Il existe un certain nombre de services dans le conteneur DI qui ont été ajoutés par l'intégration ou votre extension. Les définitions de ces services peuvent être modifiées dans la configuration. Par exemple, pour le service application.application, qui est par défaut un objet Nette\Application\Application, nous pouvons changer la classe :

services:
	application.application:
		create: MyApplication
		alteration: true

Le drapeau alteration est informatif et indique que nous ne faisons que modifier un service existant.

Nous pouvons également ajouter un service :

services:
	application.application:
		create: MyApplication
		alteration: true
		setup:
			- '$onStartup[]' = [@resource, init]

Lorsque nous réécrivons un service, nous pouvons vouloir supprimer les arguments, les éléments de configuration ou les balises d'origine, ce à quoi sert reset:

services:
	application.application:
		create: MyApplication
		alteration: true
		reset:
			- arguments
			- setup
			- tags

Un service ajouté par extension peut également être retiré du conteneur :

services:
	cache.journal: false