配置参考

OxPHP 完全通过环境变量进行配置。没有需要管理的配置文件,而且每一项设置都有默认值,因此零配置部署开箱即用。

布尔值

标记为布尔类型的变量接受一组固定的规范取值,大小写不敏感并会去除首尾空白:

  • 真值:ontrue1yes
  • 假值:offfalse0no

任何落在该集合之外的非空值——例如 ture 这样的拼写错误——会在启动时快速失败,并给出指明该变量的错误信息。这能在流量到来之前捕获配置错误,而不是悄无声息地把标志翻到错误的方向。

未设置的变量或空赋值(FOO=)会回退到文档记载的默认值。空值被特意当作未设置处理:Docker Compose / Kubernetes 中形如 FOO=${FOO} 的替换在宿主变量缺失时会产生 FOO=,而这不应导致服务器拒绝启动。

服务器

Variable Default Description
LISTEN_ADDR 0.0.0.0:80 主 HTTP 服务器的地址与端口
DOCUMENT_ROOT /var/www/html/public 提供文件和 PHP 脚本服务的根目录
ENTRY_FILE (未设置) 单一规范入口脚本。未设置 = 直接文件映射。*.php = 前端控制器。非 .php = 静态回退(SPA)。当 WORKER_MODE_ENABLED=true 时 = 工作进程引导。相对于 DOCUMENT_ROOT 解析(允许相对路径和 ..;绝对路径按原样使用)。参见路由
WORKER_MODE_ENABLED false 启用持久化工作进程模式。要求 ENTRY_FILE 指向一个 .php 脚本。布尔——参见布尔值
MAX_CONNECTIONS 10000 最大并发 TCP 连接数
TOKIO_WORKERS CPU / 2(最小 1) 异步 I/O 线程。1 = 单线程,N > 1 = 固定线程数,未设置 = 自动(CPU / 2,最小 1)

PHP 工作进程

Variable Default Description
EXECUTOR sapi PHP 执行器后端。sapi 用于执行 PHP,stub 用于不带 PHP 的基准测试
PHP_WORKERS CPU / 2(最小 1) 工作进程池大小。N = 固定池,MIN:MAX = 动态伸缩,0 = 自动
PHP_WORKERS_IDLE_SECONDS 30 动态工作进程被回收前保持空闲的秒数(仅动态模式)
QUEUE_CAPACITY 初始工作进程数 × 128 PHP 队列中最大待处理请求数。队满时返回 529。对于动态池(MIN:MAX),初始工作进程数 = 最小数量

静态工作进程与动态工作进程

PHP_WORKERS 设为单个数字以使用固定池:

bash
PHP_WORKERS=8 # Fixed 8 workers PHP_WORKERS=0 # Auto-detect: CPU / 2 (min 1)

PHP_WORKERS 设为 MIN:MAX 以启用自动伸缩:

bash
PHP_WORKERS=2:16 # Scale between 2 and 16 workers PHP_WORKERS=4:0 # 4 minimum, auto-detect maximum (CPU × 2) PHP_WORKERS=0:16 # auto-detect minimum (CPU / 4, min 1), 16 maximum

在动态模式下,当所有工作进程都繁忙时 OxPHP 会扩容工作进程,当工作进程空闲时间超过 PHP_WORKERS_IDLE_SECONDS 时会缩容。

工作进程模式

Variable Default Description
WORKER_MAX_MEMORY_MIB 0 每个工作进程被回收前的最大内存(MiB)。0 = 无限制

设置 WORKER_MODE_ENABLED=true 并让 ENTRY_FILE 指向你的工作进程引导脚本(例如 ENTRY_FILE=worker.phpENTRY_FILE=../worker.php)。此后 PHP 进程会跨请求保持存活,把引导状态(自动加载器、数据库连接)保留在内存中。当工作进程超过 WORKER_MAX_MEMORY_MIB 时会被自动回收,或者在应用调用 Worker::scheduleExit() 时按需回收。早期版本中的 WORKER_MAX_REQUESTS 旋钮已弃用并被忽略——两者都不要设置,或者迁移到 Worker::scheduleExit()

已弃用:INDEX_FILEWORKER_FILE

为向后兼容,遗留的 INDEX_FILEWORKER_FILE 变量仍会被解析。设置后,它们会在启动时输出一行 WARN 日志,并映射到新模型上:

Legacy Equivalent today
INDEX_FILE=index.php ENTRY_FILE=index.php
INDEX_FILE=index.html ENTRY_FILE=index.html
WORKER_FILE=/path/worker.php WORKER_MODE_ENABLED=true ENTRY_FILE=/path/worker.php

如果新旧同时设置,则以 ENTRY_FILE / WORKER_MODE_ENABLED 为准。可以在方便时再迁移;已弃用的形式将在未来版本中移除。

SAPI / PHP

Variable Default Description
SUPERGLOBALS_ENABLED true 在脚本执行前填充 PHP 超全局变量($_GET$_POST$_COOKIE$_FILES$_SERVERphp://input)。设为假值可跳过填充——此时请求数据只能通过对象 API(oxphp_http_request())获取。对于直接使用对象 API、希望避免在每个请求上构建超全局变量开销的应用很有用

超时

Variable Default Description
HEADER_TIMEOUT_SECONDS 5 连接建立后接收 HTTP 头部的最大秒数(Slowloris 防护)
DRAIN_TIMEOUT_SECONDS 25 优雅关闭期间等待进行中连接的最大秒数

PHP 执行时间受 PHP 自身的 max_execution_time ini 指令(以及运行时的 set_time_limit())限制,而非某个 OxPHP 环境变量。

限流

Variable Default Description
RATE_LIMIT 0(关闭) 每个 IP 在每个时间窗口内的最大请求数。0 禁用限流
RATE_WINDOW_SECONDS 60 限流窗口时长(秒)

安全

Variable Default Description
FRAME_OPTIONS DENY 点击劫持防护。DENY 阻止所有框架嵌入,SAMEORIGIN 允许同源框架嵌入,off 禁用(当你通过自己的 CSP 管理框架嵌入时使用)。同时设置 X-Frame-OptionsContent-Security-Policy: frame-ancestors。服务器安全头部是回退项:由应用设置的值(例如 PHP 的 header())优先,并且永远不会被覆盖。这对框架嵌入头部双向关联——应用设置的 X-Frame-Options 会抑制服务器的 Content-Security-Policy: frame-ancestors(在现代浏览器中 CSP 覆盖 X-Frame-Options),而包含 frame-ancestors 指令的应用 CSP 会抑制服务器的 X-Frame-Options。注意此优先级同样适用于 X-Content-Type-Options:应用设置的值会按原样保留,即便 nosniff 是它唯一的有效值——无效值会禁用该防护
TRUSTED_PROXIES (未设置) 可信反向代理网络(逗号分隔的 CIDR 或 private)。设置后,OxPHP 会使用最右非可信算法从 ForwardedRFC 7239)或 X-Forwarded-For 头部中提取真实客户端 IP。还会处理 X-Forwarded-ProtoX-Forwarded-Host,用于 $_SERVER['HTTPS']REQUEST_SCHEMESERVER_NAMESERVER_PORT。未设置 = 功能禁用
PHP_DENY_PATHS (未设置) 逗号分隔的 glob 模式,其 .php 文件绝不能通过直接 URI 执行(例如 /uploads/**,/cache/**,/admin/legacy.php)。模式可以针对整个目录或单个文件。适用于直接映射模式——传统模式和 SPA 模式;在框架模式和工作进程模式下会被忽略并给出启动警告,因为这两种模式永远不会直接执行任意 .php 文件。也涵盖通过目录索引解析到达的脚本(/uploads/uploads/index.php)。对于直接的 .php URI,匹配发生在磁盘 I/O 之前,因此被拒绝的路径无论文件是否存在都产生相同的响应(不存在存在性预言)。遗留名称 PHP_DENY_DIRS 作为已弃用的别名被接受,并会输出启动 WARN。参见 PHP 执行拒绝列表
PHP_DENY_FALLBACK 404 命中 PHP_DENY_PATHS 时返回什么。可以是一个 HTTP 状态码 400599(与 ERROR_PAGES_DIR 配合可提供自定义 HTML),或者是一个以 / 开头、指向 DOCUMENT_ROOT 内 PHP 回退脚本的 URI 路径。回退脚本会在 $_SERVER 中收到 OXPHP_DENIED_PATHOXPHP_DENIED_PATTERN。在启动时校验:脚本必须存在、规范化后位于 DOCUMENT_ROOT 内,且自身不能匹配 PHP_DENY_PATHS(防止循环)
SYMLINK_ALLOW_PATHS (未设置) 逗号分隔的绝对路径列表,在这些路径之下允许符号链接逃逸出 DOCUMENT_ROOT。每一项都必须已在磁盘上存在;相对路径和不存在的路径会中止启动。未设置 = 不允许任何符号链接逃逸。参见符号链接允许路径

特殊值 private 会展开为所有 RFC-1918 私有网络、回环地址和链路本地地址(IPv4 与 IPv6):10.0.0.0/8172.16.0.0/12192.168.0.0/16127.0.0.0/8169.254.0.0/16::1/128fc00::/7fe80::/10

TLS

Variable Default Description
TLS_CERT (未设置) PEM 编码的 TLS 证书路径。必须同时设置 TLS_CERTTLS_KEY 才能启用 TLS
TLS_KEY (未设置) PEM 编码的 TLS 私钥路径
TLS_MIN_VERSION 1.2 接受的最低 TLS 协议版本:1.21.3。即使未启用 TLS,也会在启动时(以及通过 oxphp config --check)校验——任何其他值,包括非 UTF-8 字节,都是硬性启动错误。空值被当作未设置处理

HTTP/2

Variable Default Description
H2_MAX_CONCURRENT_STREAMS PHP_WORKERS_MAX × 4(最小 32) 每个 HTTP/2 连接同时打开的最大流数
H2_MAX_PENDING_RESET 20 在关闭连接前排队的最大 RST_STREAM 帧数(Rapid Reset 防护)
H2_MAX_HEADER_LIST_BYTES 65536 每个请求解码后头部的最大总字节数
H2_KEEPALIVE_INTERVAL_SECS 20 HTTP/2 PING 帧之间的秒数;0 禁用
H2_KEEPALIVE_TIMEOUT_SECS 10 在关闭连接前等待 PING 回复的秒数

静态文件

Variable Default Description
STATIC_MAX_AGE 30d 静态文件的 Cache-Control: max-age。接受:30s5m2h30d1w1y、纯秒数(3600),或用 off 禁用该头部。取代已弃用的 STATIC_CACHE_TTL
STATIC_REVALIDATE off 布尔——参见布尔值。设为真值以对内存内容缓存启用 mtime 重新校验:每个文件的修改时间最多每 3 秒重新检查一次(按文件计,而非按请求计),过期条目会被自动逐出,因此变更会在 3 秒内变得可见。取代已弃用的 STATIC_CACHE(其中 off 的含义正好相反)。
COMPRESSION_LEVEL 4 Brotli 压缩质量(0–11)。0 禁用压缩

日志

Variable Default Description
LOG_LEVEL info 日志详细程度:tracedebuginfowarnerror
ACCESS_LOG (未设置) 按请求的访问日志:all = 每个请求,error = 仅 4xx/5xx,未设置 = 关闭
Note

ACCESS_LOG 接受 allerror。不设置它即可完全禁用访问日志。

可观测性

Variable Default Description
INTERNAL_ADDR (未设置) 内部服务器(/health/metrics/config)的地址。未设置时不会启动内部服务器。仅端口的值(:90909090)会绑定到 127.0.0.1;绑定显式的 0.0.0.0:9090 可将其暴露到主机之外
INTERNAL_ALLOW_IPS (未设置) 内部服务器的逗号分隔 CIDR/IP 允许列表。列表之外的对端在访问 /metrics/config 和插件路径时会收到 403;健康探针(/health/healthz/readyz/startupz 及其完整形式)保持可访问。未设置/为空 = 允许所有。回环地址不是隐式包含的——列出 127.0.0.1/32 以保留 localhost 访问。格式错误的列表会中止启动
ERROR_PAGES_DIR (未设置) 包含以 {status}.html 命名的自定义错误页面(例如 404.html503.html)的目录
MAX_QUERY_BODY 524288 内部查询端点的最大请求体大小(字节)(512 KiB)
TRACE_CONTEXT false 布尔——参见布尔值。为真时,启用 W3C Trace Context 传播:读取 traceparent/tracestate 头部并通过 $_SERVER 转发给 PHP

OpenTelemetry

Variable Default Description
OTEL_ENABLED false 启用 OpenTelemetry span 导出。自动设置 TRACE_CONTEXT=true。布尔——参见布尔值
OTEL_EXPORTER_OTLP_PROTOCOL grpc 导出协议:grpchttp/protobuf
OTEL_EXPORTER_OTLP_ENDPOINT http://localhost:4317(gRPC)或 http://localhost:4318(HTTP) OTLP 采集器端点
OTEL_EXPORTER_OTLP_TIMEOUT 10000 导出超时(毫秒)
OTEL_EXPORTER_OTLP_HEADERS (未设置) 认证头部:key=value,key2=value2
OTEL_SERVICE_NAME oxphp 导出 span 中的服务名
OTEL_SERVICE_VERSION (未设置) 服务版本属性
OTEL_RESOURCE_ATTRIBUTES (未设置) 额外的资源属性:env=prod,region=us-east-1
OTEL_TRACES_SAMPLER parentbased_traceidratio 采样策略:always_onalways_offtraceidratioparentbased_always_onparentbased_always_offparentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG 1.0 基于比例的采样器的采样比率(0.0–1.0)
Note

无效或超出范围的 OTEL_TRACES_SAMPLER_ARG 值会被钳制到 [0.0, 1.0] 并以 warn 级别记录日志。未知的 OTEL_TRACES_SAMPLER 值会回退到 parentbased_traceidratio 并记录日志。

APM

Variable Default Description
OTEL_APM_ENABLED false 启用 APM:自动埋点、错误捕获以及 PHP 追踪 SDK。要求 OTEL_ENABLED=true。布尔——参见布尔值
OTEL_APM_SLOW_QUERY_MS 100 慢查询阈值(毫秒)。超过此值的数据库查询会获得 oxphp.db.slow=true span 属性
OTEL_APM_DB_CAPTURE_PARAMS_ENABLED false db.params span 属性中记录绑定参数。若参数可能包含敏感数据,请在生产环境中禁用。布尔——参见布尔值
OTEL_APM_STACKTRACE_MAX_BYTES 8192 exception.stacktrace 属性的最大大小(字节)。超过上限时,堆栈跟踪会从尾部截断并带 …(truncated) 标记。0 禁用截断
OTEL_APM_MESSAGE_MAX_BYTES 4096 exception.message 属性的最大大小(字节)(默认值与 New Relic 的每属性值上限一致)。超过上限时,消息会从尾部截断并带 …(truncated) 标记。0 禁用截断

启用 APM 时,OxPHP 会自动挂钩 33 个内部 PHP 函数(PDO、mysqli、cURL、Redis、Memcached、文件 I/O)以创建子 span。无论 APM 是否启用,oxphp_apm_*() PHP 函数都会被注册——禁用时,它们是安全的空操作。

异步工作进程

Variable Default Description
ASYNC_WORKERS 0(禁用) 专用异步工作进程线程的数量。当为 0 时,异步函数(oxphp_async 等)仍会被注册,但调用时会抛出 OxPHP\Async\AsyncException。设为正值以启用后台任务执行
ASYNC_QUEUE_CAPACITY ASYNC_WORKERS × 64 异步队列中最大待处理任务数。0 = 自动(workers × 64)
ASYNC_MAX_FIBERS 256 每个工作进程并发异步任务纤程的上限。进程全局的进行中上限(排队 + 运行)为 ASYNC_MAX_FIBERS × ASYNC_WORKERS;超过它的派发会立即以 OxPHP\Async\AsyncException 被拒绝,因此扇出组合不会死锁

异步工作进程池处理从 PHP 派发的即发即忘后台任务。它独立于 PHP 工作进程池,标准请求处理并不需要它。

这三个变量中任何一个出现格式错误的值(例如 ASYNC_WORKERS=8x)都是启动错误——回退到默认值会悄无声息地禁用或错误配置该池。恰好为空的值被当作未设置处理。

共享状态

进程内并发原语(OxPHP\Shared\CounterMapChannelMutexOncePoolAtomicFlagRegistry)。API 概览参见共享状态

Variable Default Description
SHARED_ENABLED true 布尔——参见布尔值。整个 OxPHP\Shared\* 子系统的总开关
SHARED_MAX_ENTRIES 100000 所有共享条目合计的全局上限。超过后插入会以 CapacityException 失败
SHARED_MAX_BYTES 1073741824(1 GiB) 所有共享条目估算内存的全局上限
SHARED_SOFT_LIMIT_RATIO 0.7 当使用量越过 SHARED_MAX_BYTES / SHARED_MAX_ENTRIES 的这一比例时,开始丢弃最低优先级的工作
SHARED_METRICS_ENABLED true 布尔。切换 oxphp_shared_* Prometheus 暴露
SHARED_INTROSPECTION_ENABLED true 布尔。切换内部服务器上的 /__ox_shared/* 内省 API
SHARED_INTROSPECTION_PREVIEW_ENABLED true 布尔。切换内省响应中的值预览(当预览可能泄露敏感数据时禁用)
SHARED_CYCLE_DETECT_DEPTH 16 环检测期间的 BFS 深度。对合法的深层图可调高
SHARED_CYCLE_DETECT_EDGES 10000 环检测期间遍历的边数。对合法的稠密图可调高
SHARED_MAX_VALUE_SIZE 1048576(1 MiB) 每个值的大小上限。插入更大的值会快速失败
SHARED_MAX_CHANNEL_BYTES 67108864(64 MiB) 每个 channel 的负载(请求体)总量上限
SHARED_POISON_STRICT false 布尔。为真时,Mutex/Once 闭包内部的 panic 会永久性地污染该原语,而非尽力恢复
SHARED_LOCK_DIAGNOSTICS off 锁竞争诊断:offcounttrace
SHARED_LOCK_POLL_INTERVAL_MS 100 锁诊断采样器使用的轮询间隔
SHARED_PREVIEW_STRING_LIMIT 256 /entry?id=… 预览中每个字符串的截断长度
SHARED_PREVIEW_ARRAY_LIMIT 20 /entry?id=… 预览中采样的条目数

性能分析

发出 xhprof / speedscope 追踪的采样性能分析器。输出格式和查看器集成参见性能分析

Variable Default Description
PROFILER_ENABLED false 布尔——参见布尔值。总开关。所有其他 PROFILER_* 变量在启动时仍会被解析,以便拼写错误立即暴露
PROFILER_SAMPLE_RATE 0.0 请求被采样的概率(0.0–1.0)。范围之外的值会被钳制
PROFILER_INTERNAL false 布尔。为真时,对内部服务器(/health/metrics、插件端点)的请求也有资格被采样
PROFILER_AUTH_TOKEN (未设置) 可选的 bearer 令牌。设置后,oxphp_profiler_* PHP 函数要求请求携带该令牌才能启用按需性能分析
PROFILER_MAX_SPANS 50000 每个请求的性能分析 span 上限。超过上限的性能分析会被截断
PROFILER_MAX_DEPTH 256 每个采样捕获的最大调用栈深度。硬上限为 65535
PROFILER_OUTPUT_DIR /tmp/oxphp-profiles 磁盘上性能分析文件的目录
PROFILER_OUTPUT_FORMATS xhprof,speedscope 逗号分隔的要写入磁盘的输出格式列表
PROFILER_DISK_MAX_PER_SEC 10 每秒写入磁盘的性能分析文件的限流
PROFILER_RETENTION_COUNT 100 PROFILER_OUTPUT_DIR 中保留的最大性能分析文件数。较旧的文件会被清理
PROFILER_EXPORT_URL (未设置) 用于 POST 性能分析的远程端点。设置后,除非 PROFILER_OUTPUT_FORMATS 为空,否则仍会写入磁盘
PROFILER_EXPORT_FORMAT xhprof PROFILER_EXPORT_URL POST 的传输格式
PROFILER_EXPORT_AUTH_TOKEN (未设置) 随每次导出请求一起发送的可选 bearer 令牌
PROFILER_EXPORT_XHGUI (自动检测) 布尔。强制对导出负载进行 XHGui 兼容封装。未设置 = 当 PROFILER_EXPORT_URL 路径以 /run/import 结尾时自动检测(不匹配 host/query 提示)
PROFILER_EXPORT_BUGGREGATOR (自动检测) 布尔。强制使用 Buggregator 信封。未设置 = 当 PROFILER_EXPORT_URL 路径以 /api/profiler/store 结尾时自动检测。该信封始终发出 xhprof,因此对它而言 PROFILER_EXPORT_FORMAT 会被忽略(非 xhprof 值会警告,非致命)。与 PROFILER_EXPORT_XHGUI 互斥——同时启用两者是启动错误
PROFILER_EXPORT_APP_NAME (未设置) 用于项目分组的 Buggregator app_name
PROFILER_EXPORT_TAGS (未设置) Buggregator tags,格式为 key=value,key2=value2;格式错误的 token、空键或重复键都是启动错误

示例配置

开发

bash
LISTEN_ADDR=127.0.0.1:8080 DOCUMENT_ROOT=./public LOG_LEVEL=debug ACCESS_LOG=all PHP_WORKERS=1 INTERNAL_ADDR=127.0.0.1:9090

生产(框架模式)

bash
LISTEN_ADDR=0.0.0.0:80 DOCUMENT_ROOT=/var/www/html/public ENTRY_FILE=index.php PHP_WORKERS=8 QUEUE_CAPACITY=1024 LOG_LEVEL=warn ACCESS_LOG=error MAX_CONNECTIONS=10000 INTERNAL_ADDR=127.0.0.1:9090 RATE_LIMIT=100 RATE_WINDOW_SECONDS=60 TRUSTED_PROXIES=private HEADER_TIMEOUT_SECONDS=5 DRAIN_TIMEOUT_SECONDS=25 COMPRESSION_LEVEL=4 STATIC_MAX_AGE=30d

生产(工作进程模式)

bash
LISTEN_ADDR=0.0.0.0:80 DOCUMENT_ROOT=/var/www/html/public WORKER_MODE_ENABLED=true ENTRY_FILE=../worker.php PHP_WORKERS=8 WORKER_MAX_MEMORY_MIB=128 QUEUE_CAPACITY=1024 LOG_LEVEL=warn ACCESS_LOG=error INTERNAL_ADDR=127.0.0.1:9090

TLS

bash
LISTEN_ADDR=0.0.0.0:443 TLS_CERT=/etc/ssl/oxphp/cert.pem TLS_KEY=/etc/ssl/oxphp/key.pem DOCUMENT_ROOT=/var/www/html/public ENTRY_FILE=index.php

查看当前生效的配置

当内部服务器运行时,查询 /config 端点以查看已解析的配置:

bash
curl -s http://localhost:9090/config | jq .
json
{ "listen_addr": "0.0.0.0:80", "document_root": "/var/www/html/public", "entry_file": "/var/www/html/public/index.php", "log_level": "warn", "executor_type": "sapi", "php_workers": "8", "tokio_workers": 4, "queue_capacity": 1024, "max_connections": 10000, "drain_timeout_seconds": 30, "header_timeout_seconds": 5, "rate_limit": 100, "rate_window_seconds": 60, "tls_enabled": true, "compression_level": 4, "access_log": "all", "max_query_body": 524288, "worker_mode_enabled": false, "worker_max_memory_mib": 0, "static_max_age": 2592000, "static_revalidate": false, "async_workers": 0, "async_queue_capacity": 0, "async_max_fibers": 256, "async_in_flight_cap": 0, "trace_context": true, "superglobals_enabled": true, "trusted_proxies": false, "plugins": { "otel": { "enabled": true, "protocol": "grpc", "service_name": "oxphp" }, "apm": { "enabled": true, "slow_query_ms": 100, "db_capture_params": false, "hooks_registered": 33 } } }
Note

对外提供的 /config 响应会清除内部 Config 表示所携带的少数几个键:TLS 证书和密钥路径永远不会被发出(tls_enabled 表示 TLS 是否处于激活状态),internal_addrerror_pages_dir 也会被移除——这些部署拓扑和文件系统路径有利于攻击者,且指标抓取器并不需要它们。

另请参阅