Skip to content

Configuration Reference

Mikhail Deynekin edited this page Oct 11, 2026 · 2 revisions

Configuration Reference

One immutable Config value object replaces all ~35 $GLOBALS['HTML_*'] keys of v3. Unknown keys throw ConfigException at every nesting level β€” a typo is a deploy-time error, not a production mystery.

$engine = HtmlPhp\Engine::create([
    'debug'     => false,
    'charset'   => 'UTF-8',
    'templates' => [...], 'syntax' => [...], 'ssi' => [...], 'i18n' => [...],
    'cache'     => [...], 'log'    => [...], 'security' => [...], 'limits' => [...],
]);

$config->merge(['cache' => ['ttl' => 60]]);   // β†’ new instance (immutable)
$engine->config()->toArray();                 // round-trips through fromArray

Note

Canonical spec incl. the v3 key map: docs/CONFIGURATION.md Β· Migration Β§6.

templates

Key Type Default Notes
paths list<string> [] ordered roots, first match wins
namespaces map {} ['@admin' => '/path'] β†’ @admin/page.html
extension string .html appended to extension-less names
cache_file_mtimes bool true reserved

syntax

Key Type Default Notes
var_open/var_close string %{ / } primary delimiters
alt_open string #{ alternate form
trans_open string @{ translation form
tag_open/tag_close string <!--@ / --> structure tags
auto_escape bool true v3 defaulted false β€” v4 escapes by default
missing_var enum empty empty Β· keep Β· placeholder Β· throw
missing_placeholder_format string [missing:%s]
single_braces bool false {NAME} form (CSS/JS clash risk)
allow_raw_filter bool true set false for user-editable templates
strict bool false unknown filters / broken conditions & inline expressions throw
expressions bool true v5: allow inline %{= …} / #{= …}; false leaves such tags untouched (fail-closed, expr-disabled diagnostic). @If/@Set are structural and unaffected

ssi

Key Type Default Notes
enabled bool true master switch
document_root ?string null β†’ RequestContext::$documentRoot β†’ cwd
allow_parent_paths bool false ../outside-root includes (don't)
escape_echo bool true #echo escaping
echo_allow list [] restrict echo-able names (empty = all)
time_format string %A, %d-%b-%Y %H:%M:%S %Z strftime tokens
size_format enum abbrev abbrev Β· bytes
error_message ?string null emitted by failing directives
exec_mode enum deny deny Β· allow-list Β· delegate
exec_cmd_allow list [] realpath/basename-matched binaries
exec_cgi_extensions list ['php']
exec_cgi_mode string spawn spawn Β· include (in-process)
exec_delegate ?callable null required by delegate mode
process_rendered_output bool true guarded re-substitution after SSI
printenv_enabled bool true #printenv switch

i18n

Key Type Default Notes
locale string en normalized
fallback list ['en'] consulted after active locale
domain string messages
paths list [] lazy catalogue dirs (conventions)
detect bool false negotiate from Accept-Language when available
use_wordpress ?bool null null auto Β· true/false force
number_decimals int 2 Formats::number default
decimal_point / thousands_separator string . / , unknown-locale fallback
date_format / time_format / datetime_format string Y-m-d / H:i / Y-m-d H:i

cache

Key Type Default Notes
enabled bool false render-output cache
driver enum file null Β· array Β· file Β· apcu Β· wordpress (unavailable β†’ array + diagnostic)
directory string '' required for file
ttl int 0 0–30 days (0 = backend default)
prefix string htmlphp
lock_writes bool true reserved
harden_directory bool true deny-all .htaccess + index.html
Cache key composition (why two renders never collide)

sha256(version | locale | autoEscape | missingVarPolicy | ssiFlag | anchorFile | root | sha256(source) | sha256(stableScalarView(vars))) β€” objects reduce to class name / __toString, arrays recurse with sorted keys.

log

Key Type Default Notes
driver enum null null Β· array Β· errorlog Β· file Β· syslog Β· wordpress
path string '' required for file (else degrades to null)
level string warning PSR-3 gate
channel string htmlphp
forward_diagnostics bool true mirror Diagnostics to logger

security

Key Type Default Notes
allowed_tags map|null null Cleaner allow-list (null = br, p, h1–h4, strong, b, ul, ol, li, hr)
denied_extensions list phpΒ·phtmlΒ·php3–8Β·phpsΒ·pharΒ·cgiΒ·plΒ·pyΒ·rbΒ·shΒ·bashΒ·exeΒ·dllΒ·soΒ·incΒ·confΒ·configΒ·envΒ·htaccessΒ·htpasswdΒ·iniΒ·logΒ·sqlΒ·bakΒ·swpΒ·dist never includable via SSI/partials/layouts; dotfiles refused separately & unconditionally
deny_php_includes bool true belt & braces
sanitize_exec_output bool true strip control bytes from #exec output

limits

Key Default Bounds Guards
max_template_bytes 16 MiB 1 KiB–512 MiB render input
max_include_bytes 8 MiB 1 KiB–256 MiB SSI/partial includes
max_ssi_depth 16 1–128 include recursion
max_ssi_tags 256 1–10 000 directives per render
max_loop_rows 10 000 1–1 000 000 rows per loop (truncate + diagnose)
max_loop_depth 32 1–128 loop nesting
max_block_depth 64 1–1024 partial/layout nesting
max_passes 2 1–16 reserved
max_expression_length 4096 16–65 536 @If/@Set/#if sources
max_exec_output_bytes 64 KiB 1 B–16 MiB #exec capture
exec_timeout 5 1–60 seconds per process
max_diagnostics 100 1–10 000 collector cap
max_precision 100 0–1000 rounding

Out-of-bounds values throw β€” a guard can never be typo-disabled.

Enums at a glance

Config\MissingVarPolicy::{Empty, Keep, Placeholder, Throw}
Config\ExecMode::{Deny, AllowList, Delegate}
Config\SizeFormat::{Abbrev, Bytes}
Config\CacheDriver::{Null, Array, File, Apcu, WordPress}
Config\LogDriver::{Null, Array, ErrorLog, File, Syslog, WordPress}

Clone this wiki locally