Configuration
Preflow uses a combination of environment variables and PHP config files. All configuration lives in the config/ directory and .env at the project root.
Environment Variables
The .env file holds environment-specific values that should not be committed to version control. The skeleton ships a .env.example as a template.
APP_NAME=MyApp
APP_DEBUG=1
APP_KEY=base64:your-random-key-here
APP_ENGINE=twig
APP_URL=http://localhost:8080
DB_PATH=storage/data/database.sqlite
Access environment variables anywhere via getenv() or the #[Env] attribute:
use Preflow\Core\Container\Attributes\Env;
final class Mailer
{
public function __construct(
#[Env('MAIL_HOST')]
private string $host,
#[Env('MAIL_PORT', default: '587')]
private string $port,
) {}
}
APP_KEY Generation
The APP_KEY is used for HMAC token signing (component actions, CSRF). Generate one with the CLI:
php preflow key:generate
This writes a random base64-encoded key to your .env file. Never share or commit this value.
Config Files
Configuration files return plain PHP arrays. Access values anywhere using dot notation via the Config service or the #[Config] attribute.
config/app.php
Core application settings:
return [
'name' => getenv('APP_NAME') ?: 'Preflow',
'debug' => (int) getenv('APP_DEBUG'),
'timezone' => 'UTC',
'locale' => 'en',
'engine' => getenv('APP_ENGINE') ?: 'twig',
'url' => getenv('APP_URL') ?: 'http://localhost:8080',
];
config/data.php
Storage drivers and database paths:
return [
'default' => 'sqlite',
'drivers' => [
'json' => [
'path' => __DIR__ . '/../storage/data',
],
'sqlite' => [
'path' => __DIR__ . '/../' . (getenv('DB_PATH') ?: 'storage/data/database.sqlite'),
],
],
];
config/middleware.php
Global middleware stack (executed on every request):
return [
Preflow\I18n\LocaleMiddleware::class,
];
config/providers.php
Service providers to register at boot time:
return [
App\Providers\AppServiceProvider::class,
];
Accessing Config Values
Use dot notation to read nested values:
use Preflow\Core\Container\Attributes\Config;
final class BlogService
{
public function __construct(
#[Config('app.name')]
private string $appName,
#[Config('data.default', default: 'json')]
private string $defaultDriver,
) {}
}
Or use the Config instance directly:
$config = $container->get(Preflow\Core\Config\Config::class);
$config->get('app.name'); // 'Preflow'
$config->get('app.missing', 'fallback'); // 'fallback'
$config->has('data.drivers.sqlite'); // true
Debug Modes
The APP_DEBUG environment variable controls error display:
| Value | Mode | Behavior |
|---|---|---|
0 |
Production | Minimal error pages, no stack traces |
1 |
Development | Rich HTML error pages with stack traces and request details |
2 |
Verbose | Development mode plus detailed query logging and timing |
Set APP_DEBUG=0 in production. The error handler automatically switches between a developer-friendly renderer (with file paths, stack traces, and context) and a safe production page that reveals nothing to end users.