Bootstrap
Nette application is easily configured using NEON files. We'll talk about:
- how to configure your application using NEON files
- how to handle production and development modes
- how to create the DI container
In charge of setting up the environment and creating a Dependency Injection (DI) container in Nette is the Configurator class. It is used in the bootstrap file
bootstrap.php
located in the app/
folder.
Development Mode
Development mode is automatically enabled when we're running on localhost. If you want to enable it even outside of
there, for example, programmers accessing from a specific IP address, you can use setDebugMode()
:
$configurator->setDebugMode('23.75.345.200'); // one or more IP addresses
Even more secure is the combination of an IP address and a cookie. We will store a secret token into the
nette-debug' cookie, e.g. `secret1234
, and the development mode will be activated for programmers with this
combination of IP and cookie.
$configurator->setDebugMode('secret1234@23.75.345.200');
The development mode can be deactivated by:
$configurator->setDebugMode(false);
Debugging Tool Tracy
Turn on the great debugging tool Tracy, it'll store all exceptions into files in a
specified folder (__DIR__ . '/../log'
).
$configurator->enableTracy(__DIR__ . '/../log');
Caching
The configuration is loaded and processed only once, and the result is cached, which greatly speeds up the application.
Therefore, we set the setTempDirectory()
path where the cache will be saved.
$configurator->setTempDirectory(__DIR__ . '/../temp');
RobotLoader
Usually we will want to automatically load the classes using RobotLoader, so we have to start
it up and let it load classes from the directory where bootstrap.php
is located and all its subdirectories (i.e.
__DIR__
):
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->register();
An alternative way is to only use Composer PSR-4 autoloading.
Timezone
Configurator allows you to specify a timezone for your application.
$configurator->setTimeZone('Europe/Prague');
Configuration Files
Typically, configuration files are written in the NEON format. Based on the configuration files, a system DI container is generated. This is the heart of the entire application. In a separate chapter, you can read everything about configuration.
We load the configuration files using addConfig()
:
$configurator->addConfig(__DIR__ . '/config/config.neon');
The method addConfig()
can be called multiple times to add multiple files.
$configurator->addConfig(__DIR__ . '/config/common.neon');
$configurator->addConfig(__DIR__ . '/config/local.neon');
if (PHP_SAPI === 'cli') {
$configurator->addConfig(__DIR__ . '/config/cli.neon');
}
Alternatively we can use the includes
section to load more configuration files.
includes:
- parameters.php
- services.neon
- presenters.neon
If items with the same keys appear within configuration files, they will be overwritten, or merged in the case of arrays. Each subsequent
file has a higher priority in merging. The file containing the includes
section has a higher priority than the
included files.
Parameters
Parameters can be passed to the DI container by the addParameters()
method; their values must be known at compile
time. The container is always generated for the different values of these parameters.
$configurator->addParameters([
'foo' => 'bar',
'baz' => '%tempDir%',
]);
In configuration files, we can write %foo%
to access the parameter named foo
. By default, the
Configurator populates the following parameters: appDir
, wwwDir
, tempDir
,
debugMode
and consoleMode
.
Dynamic Parameters
We can also feed dynamic parameters to the DI container. Their values needn't be known at compile time: they are used at run time. Different values don't regenerate the container.
$configurator->addDynamicParameters([
'remoteIp' => $_SERVER['REMOTE_ADDR'],
]);
Environment variables could be easily made available using dynamic parameters. We can access them via
%env.variable%
in configuration files.
$configurator->addDynamicParameters([
'env' => $_ENV,
]);
External Services
We can insert an instance of a class into the DI container directly, before the DI container creates it for us. The service
must be defined with the external: true
attribute.
services:
myservice:
type: App\Model\MyCustomService
external: true
Create a new instance and insert it in bootstrap:
$configurator->addServices([
'myservice' => new App\Model\MyCustomService('foobar'),
]);
Creating a Container
The method createContainer()
generates the container class and returns its instance:
/** @var Nette\DI\Container $container */
$container = $configurator->createContainer();
In the development mode, the container is automatically updated each time you change the code or configuration files. In production mode, it is generated only once and file changes are not checked to avoid compromising performance.
index.php
If we are creating a web application, all requests are handled by one file located in the public www/
directory,
and that is index.php
. It just passes the control to the application (that is the app/
directory), to
the bootstrap file bootstrap.php
. Subsequently, index.php
retrieves from the DI container the service
that runs the web application:
$container = require __DIR__ . '/../app/bootstrap.php';
$container->getByType(Nette\Application\Application::class)
->run();