Skip to content

Settings reference

Settings are the individual configuration values Quiote reads to shape your application’s behaviour — the app name, the debug flag, which subsystems are switched on, cache and header options, and so on. Most of them are dotted core.* keys you write in your app’s settings file, Config/settings.{php,yaml,xml}.

This page is the catalog: every setting Quiote actually reads, its default, and its effect. Use it as a lookup table — the tables below are grouped by topic so you can scan to the area you need. For how config files work (formats, resolution, inheritance), see Configuration. For per-middleware settings in pipeline context, see the Middleware reference.

Quiote configuration comes from four distinct places. Each setting below states which applies:

  1. Config settings — dotted keys (core.*, and a few routing.* / validation.*) read via Config::get(), set in your settings config (PHP/YAML/XML).
  2. Factory parameters<ae:parameter> children on a factories or databases entry, passed to a class’s initialize(). Used by the session, response, database, user, and translation roles.
  3. Environment variables / PHP constants — a handful of QUIOTE_* vars and constants read directly, mostly for bootstrap and worker mode.
  4. Programmatic — logging and the DI container have no config-file surface at all; they are wired in PHP (see Logging and The DI container).

The settings you set most often. They all live under core. and can be written in any format. Many are consumed by a specific middleware — the Middleware reference documents each in pipeline context, with the exact setting-to-middleware mapping.

Config/settings.php
return [
'core.app_name' => 'MyApp',
'core.namespace_prefix' => 'MyApp',
'core.available' => true,
'core.debug' => false,
'core.developer_exceptions' => false,
'core.default_context' => 'web',
'core.use_database' => true,
'core.use_logging' => true,
'core.use_security' => true,
'core.use_translation' => false,
];
KeyDefaultEffect
core.app_nameApplication name.
core.namespace_prefix'App'Base PHP namespace for resolving models, modules, and attribute-routed actions.
core.availabletrueApplication availability flag.
core.debugfalseDebug mode. When true, config is recompiled from source on each load rather than trusting a stale compiled cache.
core.developer_exceptionsfalsetrue selects the detailed Whoops error page; false the safe generic response. Independent of core.debug. See ErrorHandlingMiddleware.
core.environment— (required)Environment name; supplied via the kernel (env) or bootstrap. Becomes readonly once set.
core.default_context'web'Default context/profile name (falls back to the QUIOTE_CONTEXT env var).
core.context_implementationContextA Context subclass to instantiate instead of the base class.
KeyDefaultEffect
core.use_databasefalseEnables the database layer. When false, DatabaseManager still exists but opens no connection.
core.use_securitytrueWhen false, all security checks are bypassed (SecurityDecision::Allow forced). See SecurityMiddleware and Authentication & authorization.
core.use_translationfalseGates whether the translation manager is returned.

Scaffolded apps also carry core.use_logging; logging itself is configured programmatically (see Logging), not by this flag.

KeyDefaultEffect
core.cache_enabledfalseMaster switch for action/view caching.
core.use_cachefalseWhether a cache instance is built for the request. Caching needs both this and core.cache_enabled.
core.cache_backend'filesystem'Set to 'apcu' to use APCu (only if apcu_enabled() at runtime; otherwise silently falls back to filesystem), or 'redis' to use a Redis pool.
core.redis_dsn'redis://127.0.0.1:6379'Connection DSN used when core.cache_backend is 'redis'. See Redis backends.
core.config_check_freshnesstrueWhen false, trusts a compiled config cache file unconditionally instead of stat-checking the source against it. Set false in production after quiote cache:warmup — mirrors Symfony’s debug=false ConfigCache. Leave true in development so edited config/validators/routes are picked up without a manual warmup.
core.routing.trust_compiled_irfalseWith attribute-based routing (AttributeRouting), skips the live #[Route] attribute scan and loads a pre-compiled routing IR dumped by quiote cache:warmup instead. Only takes effect when the routing subclass hasn’t overridden moduleDirs() to something custom (the compiled artifact only covers the scanner’s own default module-dir inputs) — falls back to a live scan otherwise. Requires re-running cache:warmup after adding, removing or moving any #[Route]-attributed action.

core.cache_enabled and core.use_cache are read by DispatchMiddleware. This is the general-purpose PSR-16 cache — separate from the APCu config-cache prewarm (core.apcu_prewarm / QUIOTE_APCU_PREWARM), which caches compiled config.

The last two keys are production-only build-time trust switches. Both trade “always correct” for “never re-check”, and both are only safe when a build step runs on every deploy.

Every config resolution (settings, factories, output_types, each module’s module.xml, each action’s validators.xml, databases, translation) normally stat-checks its source file against the compiled cache on every request — cheap once memoized per worker, but a stat-per-config-per-request cost under classic PHP-FPM, where there is no persistent worker to memoize across. Setting core.config_check_freshness to false skips that stat pair entirely once a cache file exists. Only do this after running quiote cache:warmup, and only in an environment where config genuinely doesn’t change without a redeploy.

AttributeRouting::build() likewise scans every module’s Actions/ tree on each (re)build — a recursive directory walk plus reflection-based attribute reads per action class. cache:warmup can dump that scan’s result (the routing IR) as a PHP artifact; setting core.routing.trust_compiled_ir to true loads it instead of re-scanning. The stale-artifact risk is the same shape: this is a build-time snapshot, so a route added or removed after the last cache:warmup run won’t be seen until the next warmup. Don’t enable it unless cache:warmup runs on every deploy. See cache:warmup.

KeyDefaultEffect
core.disable-framework-headersfalseIf truthy, skips the framework response-header block entirely.
core.cache-hit-header'X-Quiote-Cache-Hit'Header sent (value 1) on a cache hit; empty value suppresses it.
core.send-nosniff-headertrueWhether X-Content-Type-Options: nosniff is added when absent.
core.expose_quiote_versionini_get('expose_php')If truthy, X-Powered-By includes the framework version; otherwise just the name.
core.stealth_modefalseWhen true, framework-identifying headers are stripped off every response — any X-Quiote-* header plus the names in core.stealth_additional_headers. See StealthMiddleware.
core.stealth_additional_headers['X-Powered-By']Header names to strip in addition to the X-Quiote-* prefix (array value). Replaces the default list rather than adding to it.
core.trusted_hosts[] (no restriction)Host-header allowlist (array value). Entries wrapped in /…/ are regexes; others match case-insensitively. A non-matching Host is replaced with the first literal entry.
core.correlation_id.header'X-Correlation-Id'Inbound header adopted as the request’s correlation id (sanitized, length-capped); if absent, one is generated. Echoed back on the response. See Logging: Correlation IDs.
core.correlation_id.exposetrueWhether the correlation id is echoed back on the response under the same header.

The response-header keys (disable-framework-headers, cache-hit-header, send-nosniff-header) are read by DispatchMiddleware; the two stealth keys by StealthMiddleware, which runs outermost and removes headers on the way out rather than suppressing them at the source.

Which runtime hosts the app, and how it behaves once it does. Full context — the runtime comparison matrix, and what changes when you leave the SAPI — is on Deployment.

KeyDefaultEffect
core.worker_runtime'auto'Which worker runtime hosts the app: auto (detect), sapi, frankenphp, or an alias a package registered (roadrunner, swoole). Also settable via $QUIOTE_WORKER_RUNTIME, or the worker_runtime option to Kernel::create(), which take precedence in that order. An explicitly named runtime that isn’t hosting the process is a startup error, not a silent fallback.
core.worker.max_requests0Requests one worker process handles before the loop stops and lets the supervisor start a fresh one. 0 disables the budget, which is what RoadRunner and Swoole want — they recycle workers themselves (pool.max_jobs, worker.swoole.max_request), and a PHP-side stop mid-pool looks to them like a crashed worker.
core.worker.cleanup_interval1000How often WorkerManager runs its deep-cleanup pass. $QUIOTE_MAX_REQUESTS overrides it (and has always driven this rather than terminating the loop).
core.worker.stray_output'append'What to do with output the app writes outside the response body, on a runtime with no SAPI output channel: append it to the body (what a SAPI would have done), discard it with a log line, or throw.
core.proxy.trust_forwarded_headerstrueWhether X-Forwarded-Proto/-Host/-Port, X-Original-Host and RFC 7239 Forwarded are applied to the request. Set false when the app is reachable directly from the internet — there is no trusted-proxy allowlist, so these headers are otherwise trusted unconditionally.

The two off-SAPI runtimes ship as packages and add their own settings: worker.roadrunner.chunk_size, and the worker.swoole.* family. Both are documented on their package pages — worker-roadrunner and worker-swoole.

Read by quiote openapi:generate (see OpenAPI generation). They only affect the generated document — nothing here changes runtime behaviour.

KeyDefaultEffect
core.openapi.titlecore.app_name, else APIinfo.title of the generated document.
core.openapi.version'1.0.0'info.version — your API’s version, not the framework’s.
core.openapi.description(unset)info.description.
core.openapi.servers[]Server URLs. Either a bare list of URLs or a list of {url, description} maps.
core.openapi.exclude_routes[]fnmatch() patterns of route names to leave out (e.g. internal.*).
core.openapi.modules[]Only describe these modules (case-insensitive). Empty means all.
core.openapi.problem_responsestrueEmit the RFC 9457 error responses the pipeline actually returns (400 where an action declares validators, 500 always) plus the ProblemDetails component schema.
core.openapi.use_action_docblockstrueUse each action class’s docblock as its operation summary/description. Turn off if your action docblocks are internal notes.

Full documentation for these lives elsewhere — this table is the index:

KeyDefaultEffect
core.csrf.enabledtrueMaster CSRF switch. Full core.csrf.* set: Middleware reference; usage: Authentication & authorization.
core.expose_validation_errors_headerfalseIf true, attaches validator errors as X-Quiote-Validation-Errors on a 400 — leaks internal structure; dev/test only. See ValidationMiddleware and Input validation.

A few settings deliberately live outside core. — in XML they need a <settings prefix="…"> wrapper (see Configuration: The XML prefix attribute):

KeyDefaultEffect
routing.http_method_map[]Overrides the HTTP-verb-to-action-method map. See Routing.
validation.reject_unknown_parameters'throw'Compile-time handling of an unknown validator parameter: 'throw', 'warn', or 'off'. See Input validation and Advanced validation.
telemetry.*offOpenTelemetry tracing/metrics — telemetry.enabled, telemetry.exporter, telemetry.sampling.*, telemetry.spans.*, and more. The full table is on the Telemetry page.
mcp.*offExpose the app as a Model Context Protocol server — mcp.enabled, mcp.transports, mcp.expose_actions, mcp.auth/mcp.auth_token, and more (requires quioteframework/mcp). The full table is on Exposing your app as an MCP server.
filesystem.*local diskFile storagefilesystem.default_disk, filesystem.disks.local.root, plus filesystem.disks.{s3,gcs,azure}.* published by the corresponding packages. Requires quioteframework/filesystem and its FilesystemPlugin.
replay.*offRecord real requests as cassettes, replay them, emit regression tests — replay.enabled, replay.record, replay.store, the replay.redact.* family, and more (requires quioteframework/replay). The full table is on Record, replay & regression tests.
plugins[]The registry Config/plugins.* and PluginManager::add() write to at boot. Not a supported settings.* key to write directly — declare plugins in Config/plugins.php/.xml/.yaml instead. See Plugins and extensibility.

Telemetry is off by default; enable it and choose an exporter under the telemetry. prefix (full settings table: Telemetry):

Config/settings.php
'telemetry.enabled' => true,
'telemetry.exporter' => 'otlp',

Set during bootstrap. core.app_dir is required (supplied by the front controller / Kernel); the rest are derived from it and marked readonly — you cannot override them from settings.

KeyDefaultNotes
core.app_dir— (required)Application root. Set by the front controller before bootstrap.
core.config_dir`{app_dir}/Config`readonly
core.cache_dir`{app_dir}/cache`readonly
core.module_dir`{app_dir}/Modules`readonly
core.model_dir`{app_dir}/Models`readonly
core.template_dir`{app_dir}/Templates`readonly
core.lib_dir`{app_dir}/Lib`readonly
core.quiote_dirframework source dirreadonly
core.system_config_dir`{quiote_dir}/Config/defaults`readonly

These are <ae:parameter> children on a factories (or databases) entry — not core.* keys. See Configuration: factories.

The role is optional — omit it and the context answers a NullSessionBag. There is no setting that turns sessions on or off; configuring the slot is the switch. Its parameters reach both the cookie layer and the chosen backend, so both live in one place.

Cookie parameters, honoured by every backend:

ParameterDefaultEffect
cookie_name'QSID'Session cookie name.
session_cookie_lifetime0Cookie lifetime in seconds. 0 is a browser-session cookie.
session_cookie_securetrueHTTPS-only cookie.
session_cookie_httponlytrueHttpOnly flag.
session_cookie_samesite'Lax'SameSite attribute; null omits it.
session_migration_grace_seconds5How long a rotated-away session id keeps resolving to its replacement. See Sessions: session fixation.

Backend parameters, by factory:

FactoryParameters
FileSessionFactorydir (%core.app_dir%/cache/sessions), idle_ttl (1440), gc_probability (1), gc_divisor (100)
PdoSessionFactorydatabase (the default connection), table ('session')
RedisSessionFactorydsn (redis://127.0.0.1:6379), prefix ('session:'), ttl (1440)
S3SessionFactoryregion (us-east-1), bucket, access_key_id, secret_access_key, key_prefix ('sessions/'), endpoint
GcsSessionFactorybucket, access_key, secret_key, object_prefix ('sessions/'), endpoint
AzureBlobSessionFactoryaccount_name, account_key, container ('quiote-sessions'), endpoint
AzureTableSessionFactoryaccount_name, account_key, table ('sessions'), endpoint

See Sessions for the full treatment.

PdoDatabase:

ParameterDefaultEffect
dsn— (required)PDO DSN string.
username / passwordCredentials.
options[]PDO constructor options (::-constants are resolved).
attributesERRMODE_EXCEPTIONsetAttribute() calls; the exception error-mode default cannot be turned off, only added to.
init_queries[]SQL run immediately after connecting.
warn_mysql_charsettrueRejects unsafe SET NAMES in init_queries for MySQL DSNs.

The Doctrine (DoctrineDatabase, Doctrine2*) and PropelDatabase connectors have their own parameter sets — see the framework’s Quiote/Database/ classes.

WebResponse cookie/output parameters include cookie_lifetime (0), cookie_path, cookie_domain, cookie_secure, cookie_httponly (true), cookie_samesite ('Lax'), send_content_length (true), send_redirect_content (false), expose_quiote (true), and use_sendfile_header (false) / sendfile_header_name ('X-Sendfile').

ParameterDefaultEffect
definitions_file`{config_dir}/rbac_definitions.xml`RBAC role/permission definitions file.
storage_namespace'org.quiote.user.User'Namespace under which user attributes are keyed in the session bag.
NameDefaultEffect
QUIOTE_ENV'prod'Environment name, read into core.environment. Note: the scaffolded pub/index.php passes 'development' explicitly, so the effective default depends on your front controller.
QUIOTE_CONTEXT'web'Primary context to create/prime.
QUIOTE_MAX_REQUESTS1000Worker requests before a deep cleanup (overrides core.worker.cleanup_interval).
QUIOTE_WORKER_RUNTIMEunsetForces a worker runtime (sapi, frankenphp, roadrunner, swoole), overriding core.worker_runtime. Required to select Swoole — it is the one runtime that is never auto-detected.
QUIOTE_JSON_STRICTstrict onSet to 0 to tolerate malformed JSON bodies instead of returning 400. See PayloadParsingMiddleware.
QUIOTE_APCU_PREWARMunsetWith APCu config-cache active, forces config prewarm (1/true/yes/on).
QUIOTE_APP_DIRCLI app-dir fallback when --app-dir is not passed.
QUIOTE_USE_APCU_CONFIG_CACHE (PHP constant)If defined truthy, compiled config is cached in APCu instead of on disk.
NO_COLORStandard no-color signal honoured by AnsiTextStreamSink.

Worker mode is configurable — see Worker runtime above and Deployment for how a runtime is selected.

Settings resolve at runtime through the static Quiote\Config\Config store:

MethodBehaviour
Config::get($name, $default = null)Read a value, or the default if unset.
Config::has($name)Whether the key is set (even to null).
Config::set($name, $value, $overwrite = true, $readonly = false)Set a value; readonly keys reject further writes.
Config::isReadonly($name)Whether the key is locked (the derived path keys are).
Config::remove($name)Unset a key, unless readonly.
Config::fromArray($data)Bulk-import a flat dotted map (what compiled settings files call).
Config::resetWorkerState($preserveKeys = [])Worker-mode reset: keeps readonly keys plus named keys, drops the rest.
  • Logging — levels and sinks are programmatic, set before Kernel::run(). See Logging.
  • Telemetry category filtering — the per-category span on/off map is programmatic (Trace::setCategories() in index.php), like logging; the rest of telemetry is telemetry.* settings. See Telemetry.
  • DI container — wired entirely in PHP (attributes + Container::set()); no config-file surface. See The DI container.
  • Translation — a separate translation.xml (locales, domains, formatters), not settings.
  • Per-middleware behaviour — see the Middleware reference.
  • Event listeners — registered programmatically via Events::listen() (or a plugin’s listen()), not settings. See Events.
  • HTTP clients — named clients are configured programmatically on HttpClientFactory (or a plugin’s httpClient()), not settings. See HTTP client.
  • Pluginswhich plugins load is the plugins setting (above); what each contributes is code. See Plugins and extensibility.
  • Output types, routes, validators — their own config files; see Output types, Routing, Validation.