Nette Documentation Preview

syntax
Bootstrap
*********

<div class=perex>

Bootstrap ist ein Bootcode, der die Umgebung initialisiert, einen Dependency Injection (DI) Container erstellt und die Anwendung startet. Wir werden das besprechen:

- wie Sie Ihre Anwendung mithilfe von NEON-Dateien konfigurieren
- wie man den Produktions- und den Entwicklungsmodus handhabt
- wie man den DI-Container erstellt

</div>


Anwendungen, ob webbasiert oder als Befehlszeilenskript, beginnen mit einer Art Initialisierung der Umgebung. In früheren Zeiten konnte das eine Datei namens `include.inc.php` sein, die dafür zuständig war und in der Startdatei enthalten war.
In modernen Nette-Anwendungen wurde sie durch die Klasse `Bootstrap` ersetzt, die als Teil der Anwendung in der Datei `app/Bootstrap.php` zu finden ist. Sie könnte zum Beispiel so aussehen:

```php
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 .[#toc-index-php]
===========================

Im Falle von Webanwendungen ist die Ausgangsdatei `index.php`, die sich im öffentlichen Verzeichnis `www/` befindet. Sie überlässt es der Klasse `Bootstrap`, die Umgebung zu initialisieren und den `$configurator` zurückzugeben, der den DI-Container erstellt. Dann wird der Dienst `Application` aufgerufen, der die Webanwendung ausführt:

```php
// Initialisieren der Umgebung + Abrufen des Configurator-Objekts
$configurator = App\Bootstrap::boot();
// Erstellen eines DI-Containers
$container = $configurator->createContainer();
// DI-Container erstellt ein Nette\Application\Application-Objekt
$application = $container->getByType(Nette\Application\Application::class);
// Nette-Anwendung starten
$application->run();
```

Wie Sie sehen, hilft die Klasse [api:Nette\Bootstrap\Configurator], die wir nun genauer vorstellen werden, bei der Einrichtung der Umgebung und der Erstellung eines Dependency-Injection-Containers (DI).


Entwicklungs- vs. Produktionsmodus .[#toc-development-vs-production-mode]
=========================================================================

Nette unterscheidet zwischen zwei grundlegenden Modi, in denen eine Anfrage ausgeführt wird: Entwicklungs- und Produktionsmodus. Der Entwicklungsmodus ist auf maximalen Komfort für den Programmierer ausgerichtet, Tracy wird angezeigt, der Cache wird automatisch aktualisiert, wenn Vorlagen oder die DI-Containerkonfiguration geändert werden, usw. Im Produktionsmodus liegt der Schwerpunkt auf der Leistung, Tracy protokolliert nur Fehler und Änderungen an Vorlagen und anderen Dateien werden nicht überprüft.

Die Auswahl des Modus erfolgt durch automatische Erkennung, so dass in der Regel keine Notwendigkeit besteht, etwas manuell zu konfigurieren oder umzuschalten. Der Modus ist Entwicklung, wenn die Anwendung auf localhost läuft (d.h. IP-Adresse `127.0.0.1` oder `::1`) und kein Proxy vorhanden ist (d.h. sein HTTP-Header). Ansonsten läuft sie im Produktionsmodus.

Wenn Sie den Entwicklungsmodus in anderen Fällen aktivieren möchten, z. B. für Programmierer, die von einer bestimmten IP-Adresse aus zugreifen, können Sie `setDebugMode()` verwenden:

```php
$configurator->setDebugMode('23.75.345.200'); // eine oder mehrere IP-Adressen
```

Wir empfehlen auf jeden Fall, eine IP-Adresse mit einem Cookie zu kombinieren. Wir speichern ein geheimes Token im `nette-debug` Cookie, z.B. `secret1234`, und der Entwicklungsmodus wird für Programmierer mit dieser Kombination von IP und Cookie aktiviert.

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

Wir können den Entwicklermodus auch komplett abschalten, sogar für localhost:

```php
$configurator->setDebugMode(false);
```

Beachten Sie, dass der Wert `true` den Entwicklermodus standardmäßig einschaltet, was auf einem Produktionsserver niemals passieren sollte.


Debugging-Werkzeug Tracy .[#toc-debugging-tool-tracy]
=====================================================

Zur einfachen Fehlersuche werden wir das großartige Tool [Tracy |tracy:] einschalten. Im Entwicklermodus zeigt es Fehler an und im Produktionsmodus protokolliert es Fehler in das angegebene Verzeichnis:

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


Temporäre Dateien .[#toc-temporary-files]
=========================================

Nette verwendet den Cache für DI-Container, RobotLoader, Vorlagen usw. Daher ist es notwendig, den Pfad zu dem Verzeichnis festzulegen, in dem der Cache gespeichert werden soll:

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

Unter Linux oder macOS setzen Sie die [Schreibrechte |nette:troubleshooting#Setting directory permissions] für die Verzeichnisse `log/` und `temp/`.


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

Normalerweise wollen wir die Klassen automatisch mit [RobotLoader |robot-loader:] laden, also müssen wir ihn starten und ihn Klassen aus dem Verzeichnis laden lassen, in dem sich `Bootstrap.php` befindet (d.h. `__DIR__`) und aus allen seinen Unterverzeichnissen:

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

Eine alternative Möglichkeit ist, nur das automatische Laden von [Composer |best-practices:composer] PSR-4 zu verwenden.


Zeitzone .[#toc-timezone]
=========================

Configurator ermöglicht es Ihnen, eine Zeitzone für Ihre Anwendung festzulegen.

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


DI-Container-Konfiguration .[#toc-di-container-configuration]
=============================================================

Teil des Boot-Prozesses ist die Erstellung eines DI-Containers, d.h. einer Fabrik für Objekte, die das Herzstück der gesamten Anwendung ist. Dabei handelt es sich um eine PHP-Klasse, die von Nette generiert und in einem Cache-Verzeichnis gespeichert wird. Die Factory erzeugt wichtige Anwendungsobjekte, und Konfigurationsdateien weisen sie an, wie sie zu erstellen und zu konfigurieren sind, wodurch wir das Verhalten der gesamten Anwendung beeinflussen.

Konfigurationsdateien werden normalerweise im [NEON-Format |neon:format] geschrieben. [Was konfiguriert werden kann |nette:configuring], können Sie [hier |nette:configuring] nachlesen.

.[tip]
Im Entwicklungsmodus wird der Container jedes Mal automatisch aktualisiert, wenn Sie den Code oder die Konfigurationsdateien ändern. Im Produktionsmodus wird er nur einmal generiert und Dateiänderungen werden nicht überprüft, um die Leistung zu maximieren.

Konfigurationsdateien werden mit `addConfig()` geladen:

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

Die Methode `addConfig()` kann mehrfach aufgerufen werden, um mehrere Dateien hinzuzufügen.

```php
$configurator->addConfig($appDir . '/config/common.neon');
$configurator->addConfig($appDir . '/config/services.neon');
if (PHP_SAPI === 'cli') {
	$configurator->addConfig($appDir . '/config/cli.php');
}
```

Der Name `cli.php` ist kein Tippfehler, die Konfiguration kann auch in eine PHP-Datei geschrieben werden, die sie als Array zurückgibt.

Alternativ können wir auch den [Abschnitt`includes`  |dependency-injection:configuration#including files] verwenden, um weitere Konfigurationsdateien zu laden.

Wenn Elemente mit denselben Schlüsseln in Konfigurationsdateien vorkommen, werden sie [überschrieben oder |dependency-injection:configuration#Merging] im Falle von Arrays [zusammengeführt |dependency-injection:configuration#Merging]. Die später eingebundene Datei hat eine höhere Priorität als die vorherige. Die Datei, in der der Abschnitt `includes` aufgeführt ist, hat eine höhere Priorität als die in ihr enthaltenen Dateien.


Statische Parameter .[#toc-static-parameters]
---------------------------------------------

Parameter, die in Konfigurationsdateien verwendet werden, können [im Abschnitt `parameters` |dependency-injection:configuration#parameters] definiert und auch von der Methode `addStaticParameters()` übergeben (oder überschrieben) werden (sie hat den Alias `addParameters()`). Wichtig ist, dass unterschiedliche Parameterwerte die Erzeugung zusätzlicher DI-Container, d.h. zusätzlicher Klassen, bewirken.

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

In Konfigurationsdateien können wir die übliche Notation `%projectId%` verwenden, um auf den Parameter `projectId` zuzugreifen.


Dynamische Parameter .[#toc-dynamic-parameters]
-----------------------------------------------

Wir können dem Container auch dynamische Parameter hinzufügen, deren unterschiedliche Werte, im Gegensatz zu statischen Parametern, nicht die Erzeugung neuer DI-Container verursachen.

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

Umgebungsvariablen können mit dynamischen Parametern leicht verfügbar gemacht werden. Wir können über `%env.variable%` in Konfigurationsdateien auf sie zugreifen.

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


Standard-Parameter .[#toc-default-parameters]
---------------------------------------------

Sie können die folgenden statischen Parameter in den Konfigurationsdateien verwenden:

- `%appDir%` ist der absolute Pfad zu dem Verzeichnis, in dem sich die Datei `Bootstrap.php` befindet
- `%wwwDir%` ist der absolute Pfad zu dem Verzeichnis, das die `index.php` Eintragsdatei enthält
- `%tempDir%` ist der absolute Pfad zu dem Verzeichnis für temporäre Dateien
- `%vendorDir%` ist der absolute Pfad zu dem Verzeichnis, in dem Composer die Bibliotheken installiert
- `%debugMode%` gibt an, ob sich die Anwendung im Debug-Modus befindet
- `%consoleMode%` zeigt an, ob die Anfrage über die Befehlszeile kam


Importierte Dienste .[#toc-imported-services]
---------------------------------------------

Wir gehen jetzt in die Tiefe. Obwohl der Zweck eines DI-Containers darin besteht, Objekte zu erstellen, kann es in Ausnahmefällen erforderlich sein, ein vorhandenes Objekt in den Container einzufügen. Wir tun dies, indem wir den Dienst mit dem Attribut `imported: true` definieren.

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

Erstellen Sie eine neue Instanz und fügen Sie sie in Bootstrap ein:

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


Verschiedene Umgebungen .[#toc-different-environments]
======================================================

Es steht Ihnen frei, die Klasse `Bootstrap` an Ihre Bedürfnisse anzupassen. Sie können der Methode `boot()` Parameter hinzufügen, um Webprojekte zu unterscheiden, oder andere Methoden hinzufügen, wie `bootForTests()`, die die Umgebung für Unit-Tests initialisiert, `bootForCli()` für Skripte, die von der Befehlszeile aus aufgerufen werden, und so weiter.

```php
public static function bootForTests(): Configurator
{
	$configurator = self::boot();
	Tester\Environment::setup(); // Nette Tester Initialisierung
	return $configurator;
}
```

Bootstrap

Bootstrap ist ein Bootcode, der die Umgebung initialisiert, einen Dependency Injection (DI) Container erstellt und die Anwendung startet. Wir werden das besprechen:

  • wie Sie Ihre Anwendung mithilfe von NEON-Dateien konfigurieren
  • wie man den Produktions- und den Entwicklungsmodus handhabt
  • wie man den DI-Container erstellt

Anwendungen, ob webbasiert oder als Befehlszeilenskript, beginnen mit einer Art Initialisierung der Umgebung. In früheren Zeiten konnte das eine Datei namens include.inc.php sein, die dafür zuständig war und in der Startdatei enthalten war. In modernen Nette-Anwendungen wurde sie durch die Klasse Bootstrap ersetzt, die als Teil der Anwendung in der Datei app/Bootstrap.php zu finden ist. Sie könnte zum Beispiel so aussehen:

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

Im Falle von Webanwendungen ist die Ausgangsdatei index.php, die sich im öffentlichen Verzeichnis www/ befindet. Sie überlässt es der Klasse Bootstrap, die Umgebung zu initialisieren und den $configurator zurückzugeben, der den DI-Container erstellt. Dann wird der Dienst Application aufgerufen, der die Webanwendung ausführt:

// Initialisieren der Umgebung + Abrufen des Configurator-Objekts
$configurator = App\Bootstrap::boot();
// Erstellen eines DI-Containers
$container = $configurator->createContainer();
// DI-Container erstellt ein Nette\Application\Application-Objekt
$application = $container->getByType(Nette\Application\Application::class);
// Nette-Anwendung starten
$application->run();

Wie Sie sehen, hilft die Klasse Nette\Bootstrap\Configurator, die wir nun genauer vorstellen werden, bei der Einrichtung der Umgebung und der Erstellung eines Dependency-Injection-Containers (DI).

Entwicklungs- vs. Produktionsmodus

Nette unterscheidet zwischen zwei grundlegenden Modi, in denen eine Anfrage ausgeführt wird: Entwicklungs- und Produktionsmodus. Der Entwicklungsmodus ist auf maximalen Komfort für den Programmierer ausgerichtet, Tracy wird angezeigt, der Cache wird automatisch aktualisiert, wenn Vorlagen oder die DI-Containerkonfiguration geändert werden, usw. Im Produktionsmodus liegt der Schwerpunkt auf der Leistung, Tracy protokolliert nur Fehler und Änderungen an Vorlagen und anderen Dateien werden nicht überprüft.

Die Auswahl des Modus erfolgt durch automatische Erkennung, so dass in der Regel keine Notwendigkeit besteht, etwas manuell zu konfigurieren oder umzuschalten. Der Modus ist Entwicklung, wenn die Anwendung auf localhost läuft (d.h. IP-Adresse 127.0.0.1 oder ::1) und kein Proxy vorhanden ist (d.h. sein HTTP-Header). Ansonsten läuft sie im Produktionsmodus.

Wenn Sie den Entwicklungsmodus in anderen Fällen aktivieren möchten, z. B. für Programmierer, die von einer bestimmten IP-Adresse aus zugreifen, können Sie setDebugMode() verwenden:

$configurator->setDebugMode('23.75.345.200'); // eine oder mehrere IP-Adressen

Wir empfehlen auf jeden Fall, eine IP-Adresse mit einem Cookie zu kombinieren. Wir speichern ein geheimes Token im nette-debug Cookie, z.B. secret1234, und der Entwicklungsmodus wird für Programmierer mit dieser Kombination von IP und Cookie aktiviert.

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

Wir können den Entwicklermodus auch komplett abschalten, sogar für localhost:

$configurator->setDebugMode(false);

Beachten Sie, dass der Wert true den Entwicklermodus standardmäßig einschaltet, was auf einem Produktionsserver niemals passieren sollte.

Debugging-Werkzeug Tracy

Zur einfachen Fehlersuche werden wir das großartige Tool Tracy einschalten. Im Entwicklermodus zeigt es Fehler an und im Produktionsmodus protokolliert es Fehler in das angegebene Verzeichnis:

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

Temporäre Dateien

Nette verwendet den Cache für DI-Container, RobotLoader, Vorlagen usw. Daher ist es notwendig, den Pfad zu dem Verzeichnis festzulegen, in dem der Cache gespeichert werden soll:

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

Unter Linux oder macOS setzen Sie die Schreibrechte für die Verzeichnisse log/ und temp/.

RobotLoader

Normalerweise wollen wir die Klassen automatisch mit RobotLoader laden, also müssen wir ihn starten und ihn Klassen aus dem Verzeichnis laden lassen, in dem sich Bootstrap.php befindet (d.h. __DIR__) und aus allen seinen Unterverzeichnissen:

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

Eine alternative Möglichkeit ist, nur das automatische Laden von Composer PSR-4 zu verwenden.

Zeitzone

Configurator ermöglicht es Ihnen, eine Zeitzone für Ihre Anwendung festzulegen.

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

DI-Container-Konfiguration

Teil des Boot-Prozesses ist die Erstellung eines DI-Containers, d.h. einer Fabrik für Objekte, die das Herzstück der gesamten Anwendung ist. Dabei handelt es sich um eine PHP-Klasse, die von Nette generiert und in einem Cache-Verzeichnis gespeichert wird. Die Factory erzeugt wichtige Anwendungsobjekte, und Konfigurationsdateien weisen sie an, wie sie zu erstellen und zu konfigurieren sind, wodurch wir das Verhalten der gesamten Anwendung beeinflussen.

Konfigurationsdateien werden normalerweise im NEON-Format geschrieben. Was konfiguriert werden kann, können Sie hier nachlesen.

Im Entwicklungsmodus wird der Container jedes Mal automatisch aktualisiert, wenn Sie den Code oder die Konfigurationsdateien ändern. Im Produktionsmodus wird er nur einmal generiert und Dateiänderungen werden nicht überprüft, um die Leistung zu maximieren.

Konfigurationsdateien werden mit addConfig() geladen:

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

Die Methode addConfig() kann mehrfach aufgerufen werden, um mehrere Dateien hinzuzufügen.

$configurator->addConfig($appDir . '/config/common.neon');
$configurator->addConfig($appDir . '/config/services.neon');
if (PHP_SAPI === 'cli') {
	$configurator->addConfig($appDir . '/config/cli.php');
}

Der Name cli.php ist kein Tippfehler, die Konfiguration kann auch in eine PHP-Datei geschrieben werden, die sie als Array zurückgibt.

Alternativ können wir auch den Abschnittincludes verwenden, um weitere Konfigurationsdateien zu laden.

Wenn Elemente mit denselben Schlüsseln in Konfigurationsdateien vorkommen, werden sie überschrieben oder im Falle von Arrays zusammengeführt. Die später eingebundene Datei hat eine höhere Priorität als die vorherige. Die Datei, in der der Abschnitt includes aufgeführt ist, hat eine höhere Priorität als die in ihr enthaltenen Dateien.

Statische Parameter

Parameter, die in Konfigurationsdateien verwendet werden, können im Abschnitt parameters definiert und auch von der Methode addStaticParameters() übergeben (oder überschrieben) werden (sie hat den Alias addParameters()). Wichtig ist, dass unterschiedliche Parameterwerte die Erzeugung zusätzlicher DI-Container, d.h. zusätzlicher Klassen, bewirken.

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

In Konfigurationsdateien können wir die übliche Notation %projectId% verwenden, um auf den Parameter projectId zuzugreifen.

Dynamische Parameter

Wir können dem Container auch dynamische Parameter hinzufügen, deren unterschiedliche Werte, im Gegensatz zu statischen Parametern, nicht die Erzeugung neuer DI-Container verursachen.

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

Umgebungsvariablen können mit dynamischen Parametern leicht verfügbar gemacht werden. Wir können über %env.variable% in Konfigurationsdateien auf sie zugreifen.

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

Standard-Parameter

Sie können die folgenden statischen Parameter in den Konfigurationsdateien verwenden:

  • %appDir% ist der absolute Pfad zu dem Verzeichnis, in dem sich die Datei Bootstrap.php befindet
  • %wwwDir% ist der absolute Pfad zu dem Verzeichnis, das die index.php Eintragsdatei enthält
  • %tempDir% ist der absolute Pfad zu dem Verzeichnis für temporäre Dateien
  • %vendorDir% ist der absolute Pfad zu dem Verzeichnis, in dem Composer die Bibliotheken installiert
  • %debugMode% gibt an, ob sich die Anwendung im Debug-Modus befindet
  • %consoleMode% zeigt an, ob die Anfrage über die Befehlszeile kam

Importierte Dienste

Wir gehen jetzt in die Tiefe. Obwohl der Zweck eines DI-Containers darin besteht, Objekte zu erstellen, kann es in Ausnahmefällen erforderlich sein, ein vorhandenes Objekt in den Container einzufügen. Wir tun dies, indem wir den Dienst mit dem Attribut imported: true definieren.

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

Erstellen Sie eine neue Instanz und fügen Sie sie in Bootstrap ein:

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

Verschiedene Umgebungen

Es steht Ihnen frei, die Klasse Bootstrap an Ihre Bedürfnisse anzupassen. Sie können der Methode boot() Parameter hinzufügen, um Webprojekte zu unterscheiden, oder andere Methoden hinzufügen, wie bootForTests(), die die Umgebung für Unit-Tests initialisiert, bootForCli() für Skripte, die von der Befehlszeile aus aufgerufen werden, und so weiter.

public static function bootForTests(): Configurator
{
	$configurator = self::boot();
	Tester\Environment::setup(); // Nette Tester Initialisierung
	return $configurator;
}