Spiral makes it super easy to set up your application with config files. All the config files live in the
app/config
directory, and they let you configure things like connection to a database, set up cache storage, manage
queues, etc.
You don't even have to create any config files yourself, because Spiral comes with a default setup. But if you want to, you can also use environment variables to change the main parameters of your application.
Note
Caching the config files is not necessary as they are only loaded once during application bootstrapping and not reloaded unless the application is restarted.
Using environment variables is a great way to separate the configuration of your application from the code itself. This makes it easy to store sensitive information like database credentials, API keys, and other configs that you don't want to hardcode into your application.
Spiral integrates with Dotenv through the
Spiral\DotEnv\Bootloader\DotenvBootloader
class. This bootloader is responsible for loading the environment variables
from the .env
file and making them available to the application.
It is a common practice to include a .env.sample
file in a new project which can be used as a guide for setting up the
environment variables.
# Environment (prod or local)
APP_ENV=local
# Debug mode set to TRUE disables view caching and enables higher verbosity
DEBUG=true
VERBOSITY_LEVEL=verbose # basic, verbose, debug
# Set to an application specific value, used to encrypt/decrypt cookies etc
ENCRYPTER_KEY=...
# Monolog
MONOLOG_DEFAULT_CHANNEL=default
MONOLOG_DEFAULT_LEVEL=DEBUG # DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, EMERGENCY
# Queue
QUEUE_CONNECTION=roadrunner
# Cache
CACHE_STORAGE=roadrunner
# Telemetry
TELEMETRY_DRIVER=null
# Serializer
DEFAULT_SERIALIZER_FORMAT=json # csv, xml, yaml
# Session
SESSION_LIFETIME=86400
SESSION_COOKIE=sid
# Authorization
AUTH_TOKEN_TRANSPORT=cookie
AUTH_TOKEN_STORAGE=session
# Mailer
MAILER_DSN=
MAILER_FROM="My site <no-reply@site.com>"
Warning
A variable that is defined in the$_SERVER
or$_ENV
superglobal will take precedence over the value of the same variable that is defined in the.env
file.
The values from the .env
the file will be copied to your application environment and available
via Spiral\Boot\EnvironmentInterface
or the env
function.
Variable | Description |
---|---|
APP_ENV |
The current application environment. (prod , stage , testing , local ). Default: local |
DEBUG |
Debug mode. Default: false |
TOKENIZER_CACHE_TARGETS |
Cache targets for tokenizer. (Bool) Default: false |
ENCRYPTER_KEY |
Encryption key. |
VERBOSITY_LEVEL |
Verbosity level. (basic , verbose , debug ). Default: verbose |
MONOLOG_DEFAULT_CHANNEL |
Default channel name from app/config/monolog.php . Default: 'default' |
QUEUE_CONNECTION |
Queue connection name from app/config/queue.php . Default: sync |
BROADCAST_CONNECTION |
Broadcast connection. (log , null , centrifugo ). Default: null |
CACHE_STORAGE |
Cache storage from app/config/cache.php |
TELEMETRY_DRIVER |
Telemetry driver. (null , log , otel ). Default: null |
LOCALE |
Default locale.. Default: en |
DEFAULT_SERIALIZER_FORMAT |
Default serializer format. (json , serializer ) Default: json |
AUTH_TOKEN_TRANSPORT |
Authorization token transport. (cookie , header ). Default: cookie |
AUTH_TOKEN_STORAGE |
Authorization token storage. (session , cycle ). Default: session |
SESSION_LIFETIME |
Session lifetime. Default: 86400 |
SESSION_COOKIE |
Session cookie name. Default: sid |
VIEW_CACHE |
View cache. Default: DEBUG !== true |
MAILER_DSN |
Mailer DSN. |
MAILER_FROM |
Mailer from. Default: Spiral <sendit@local.host> |
MAILER_QUEUE_CONNECTION |
Mailer queue connection. Default: a value from QUEUE_CONNECTION variable |
You can access environment variables using Spiral\Boot\EnvironmentInterface
use Spiral\Boot\EnvironmentInterface;
final class GithubClient
{
public function __construct(
private readonly EnvironmentInterface $env
) {}
public function getAccessToken(): ?string
{
return $this->env->get('GITHUB_ACCESS_TOKEN');
}
}
or via a short function env()
return [
'access_token' => env('GITHUB_ACCESS_TOKEN'),
// ...
];
Remember that the values in .env
will be pre-processed, the following changes will take place:
Value | PHP Value |
---|---|
true | true |
(true) | true |
false | false |
(false) | false |
null | null |
(null) | null |
empty | '' |
Note
The quotes around strings will be stripped automatically.
While environment variables are a great way to configure certain options of your application, there may be cases where you need to make more complex or fine-grained changes to the configuration that are not possible or practical to do with environment variables alone. In such cases, you can directly modify the config files for the specific components that you want to change.
For example, you can change the default HTTP headers:
return [
'basePath' => '/',
'headers' => [
'Server' => 'Spiral',
'Content-Type' => 'text/html; charset=UTF-8'
],
'middleware' => [],
];
In Spiral, all config objects are injectable, which makes it easy to use them in your application.
use Spiral\Http\Config\HttpConfig;
final class HttpClient
{
private readonly string $basePath;
public function __construct(
HttpConfig $config // <-- Container will automatically load values from app/config/http.php
) {
$this->basePath = $this->config->getBasePath();
}
}
Each injectable config class in Spiral contains
a CONFIG constant that defines the name of
the corresponding config file. When the container resolves an injectable config object, it automatically loads all
values from the config file and assigns them to the $config
property of the config object.
Note
When a config object loads its associated config file, it automatically merges it with the default settings defined in the config class. This means that you don't have to include every single option in your config file and only the ones you want to change. The default settings are used as a fallback if a value is not present in the config file.
For example, for HTTP config:
final class HttpConfig extends InjectableConfig
{
const CONFIG = 'http';
// ...
}
Note
See the reference for each component configuration in the related documentation section.
The current application environment is determined via the APP_ENV
variable. You may access this value using the
Spiral\Boot\Environment\AppEnvironment
injectable enum class.
See more
Read more about injectable enums in the Advanced — Container injectors section.
When you request the AppEnvironment
from the container it will automatically inject an Enum with the correct value.
use Spiral\Boot\Environment\AppEnvironment;
use Psr\Http\Server\MiddlewareInterface;
final class ErrorHandlerMiddleware implements MiddlewareInterface
{
public function __construct(
private readonly AppEnvironment $env
) {
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
try {
return $handler->handle($request);
} catch (Throwable $e) {
if ($this->env->isProduction()) {
// ...
}
// ...
}
}
}
The current debug mode is determined via the DEBUG
variable. You may access this value using the
Spiral\Boot\Environment\DebugMode
injectable enum class.
use Spiral\Boot\Environment\DebugMode;
use Psr\Http\Server\MiddlewareInterface;
final class ErrorHandlerMiddleware implements MiddlewareInterface
{
public function __construct(
private readonly DebugMode $debug
) {
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
try {
return $handler->handle($request);
} catch (Throwable $e) {
if ($this->debug->isEnabled()) {
// ...
}
// ...
}
}
}
The current verbosity level is determined via the VERBOSITY_LEVEL
variable. You may access this value using the
Spiral\Exceptions\Verbosity
injectable enum class.
use Spiral\Exceptions\Verbosity;
use Psr\Http\Server\MiddlewareInterface;
final class ErrorHandlerMiddleware implements MiddlewareInterface
{
public function __construct(
private readonly Verbosity $verbosity
) {
}
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
try {
return $handler->handle($request);
} catch (Throwable $e) {
if ($this->verbosity === Verbosity::BASIC)
// ...
}
if ($this->verbosity === Verbosity::VERBOSE)
// ...
}
// ...
}
}
}
Now, dive deeper into the fundamentals by reading some articles: