3: 运行时配置
data/app.json 描述了 build,即编译的内容。本章涵盖 runtime,即每个请求发生的事情。该配置位于 www/app.php(对于阶段/发布,位于 release/www/app.php)作为 phlo_app(...) 的参数。
<?php
require('/srv/phlo/phlo.php');
phlo_app (
id: 'Example',
host: 'dev.example.nl',
auth: true,
build: true,
debug: true,
app: '/srv/example.nl/',
)
每个键都是一个 named argument,同时也成为一个 PHP constant,可以在您的应用程序中的任何地方作为裸字(host、data、composer 等)使用。您自己的自定义键也适用相同的规则。
3.1: 身份和主机
| 键 | 默认 | 目的 |
|---|---|---|
id |
无 | 应用的自由格式名称,由 Phlo Control Center、Phlo Dashboard 和日志使用 |
host |
null |
此入口点允许运行的虚拟主机。Phlo 拒绝不匹配的请求,以避免意外的跨主机响应 |
3.2: 模式: `build`, `debug`, `auth`, `thread`
| 键 | 默认 | 效果 |
|---|---|---|
build |
false |
启用 build/lint/reflect CLI,并允许 Phlo 在每个请求中检测和重新编译更改的源代码 |
debug |
false |
加载 debug.php,激活 debug() / dx() / 调试助手,提供完整的堆栈跟踪,而不是通用的 500 错误 |
auth |
false |
使用 data/auth.ini 中的凭据进行全站 HTTP Basic 认证 |
thread |
false |
工作模式(见 X.7),true = 无限,整数 = 每个工作线程的请求数量 |
请勿组合:build: true 和 thread: true。Build 在请求之间写入文件;在长时间运行的工作线程中这是不安全的。如果两者都开启,Phlo 会抛出运行时错误。
要求:auth: true 需要 build: true。如果在没有 build 的情况下设置了 auth,Phlo 在启动时会出错。(这是一个实现细节:全站认证处理程序在 build 层中提供。为了保护非 build 阶段的主机,请在 Phlo 前面的 Web 服务器中放置 HTTP Basic 认证。)
控制中心路径:当 build: true 和 debug: true 时,Phlo 控制中心会自动挂载在 /phlo,无需配置。使用可选的 control: 键将其挂载到不同的路径(control: 'admin' 在 /admin 提供服务)或设置 control: false 以关闭它。较旧的 dashboard: 键执行相同的工作,并且目前仍然有效,但 control: 是当前名称。在非 build+debug 状态下,它始终处于关闭状态。
3.3: 路径
只有 app 是必需的。其余部分默认为 app 的子目录:
| 键 | 默认值 | 预期用途 |
|---|---|---|
app |
(必需) | 应用根目录 |
data |
<app>/data/ |
配置 (app.json, auth.ini)、凭据、运行时状态 |
php |
<app>/php/ |
生成的 PHP,只有在发布输出位于其他位置时才更改此项 |
www |
<app>/www/ |
Web 根目录 |
您的发布入口点通常设置为 app: '<app>/release/' 和 php: '<app>/release/',以便在不使用构建模式的情况下提供发布输出。
3.4: 控制中心和 WebSocket
| 键 | 默认值 | 效果 |
|---|---|---|
control |
'phlo' 与 build+debug,否则为 false |
控制 UI 所在的 URL 前缀。例如 'beheer' → /beheer;false = 关闭 |
websocket |
null |
此应用程序运行 phloWS 的端口。成为常量 websocket,由 wsCast() 使用 |
控制 UI 需要 build: true。有关 phloWS 设置,请参见 WebSocket 章节。
3.5: Composer 自动加载
想要使用 vendor/ 中的 PHP 包吗?提供路径:
phlo_app (
composer: '/srv/example.nl/',
...
)
然后,Phlo 注册一个 lazy autoloader,仅在需要解析未知类时加载 <composer>/vendor/autoload.php。如果您从未接触 Composer 包,则没有冷启动成本;一旦您使用它,就会完全加载 Composer。
约定:composer: '<app>/data/'(composer.json 和 vendor/ 将位于 data/ 中,位于 webroot 之外)。
3.6: 跟踪和 CLI
| 键 | 默认值 | 效果 |
|---|---|---|
trace |
false |
启用跟踪模式,参见 Trace 章节 |
cli |
'php-zts'(如果是 ZTS)或 'php' |
Phlo 用于子进程(构建、任务、websocket)的 PHP 二进制文件路径。如果您的系统有非标准的 PHP 二进制文件,请覆盖此项 |
cli在 v4 中是一个字符串(路径),而不是 v1 中的布尔值。
3.7: Worker模式规则
thread: true 将 Phlo 设置为长时间运行的工作模式(FrankenPHP, ReactPHP, RoadRunner)。运行时在请求之间保持在内存中。您需要了解三个规则:
1. 在 HTTP 路径中不要使用 die() 或 exit()。 两者都会终止整个工作进程。使用 return 或让终止调用(view()、apply()、location())发送响应。
2. 静态属性中不要有请求状态。 静态属性在工作进程中请求之间存活;请求 A 的用户数据会泄漏到请求 B 中。对于工作安全的缓存(类结构、计算的元数据),静态属性是可以的,但不适用于会话、用户、有效负载、时间或数据库状态。
3. 用 $objPers = true 标记长生命周期对象。 默认情况下,Phlo 在请求之间清除其实例映射。对于您明确希望重用的对象(数据库连接、预处理语句),设置 $this->objPers = true,以便清理时不影响它们。
3.8: 自定义键:您自己的常量
您传递给 phlo_app() 的每个额外命名参数都会自动成为 PHP 常量。这是声明应用程序范围路径或功能标志的方法:
phlo_app (
app: '/srv/example.nl/',
langs: '/srv/example.nl/langs/',
files: '/srv/example.nl/files/',
uploads: '/srv/example.nl/data/uploads/',
)
之后可以直接在 .phlo 中使用:
$dict = parse_ini_file(langs.'en.ini')
$path = files.'avatars/'.$user->id.'.jpg'
$url = uploads
reflect::runtime 显示所有定义的常量。对于发现应用程序提供的内容而无需打开 www/app.php 非常有用。
3.9: 示例:开发和发布并排显示
phlo_app (
id: 'Example',
host: 'dev.example.nl',
auth: true,
build: true,
debug: true,
trace: true,
app: '/srv/example.nl/',
composer: '/srv/example.nl/data/',
websocket: 3001,
langs: '/srv/example.nl/langs/',
)
phlo_app (
id: 'Example',
host: 'example.nl',
thread: true,
app: '/srv/example.nl/release/',
php: '/srv/example.nl/release/',
data: '/srv/example.nl/data/',
composer: '/srv/example.nl/data/',
websocket: 3001,
langs: '/srv/example.nl/langs/',
)
开发环境具有构建、调试、认证、控制中心和跟踪功能。发布环境具有工作模式(thread),并将 webroot/php 输出指向 release/。data、composer 和 langs 保持不变,这是共享状态。
3.10: 请求和响应对象
两个运行时对象携带每个请求。%req(读取)和%res(写入)始终可用。
%req 计算属性:
| 属性 | 包含内容 |
|---|---|
%req->method |
HTTP 动词,转换为大写 |
%req->path |
请求路径,不带前导斜杠 |
%req->part($i) |
按索引获取路径段 |
%req->query |
解析后的查询字符串数组 |
%req->async |
当请求来自 phlo.js(SPA 导航,异步表单)时为 true |
%req->cli |
当从命令行运行时为 true |
%req->secure, %req->scheme, %req->base, %req->url |
URL 部分,计算一次 |
%req->referer, %req->acceptLanguage |
常见头部,已标准化 |
%res 表面:
| 成员 | 功能 |
|---|---|
%res->header($key, $value) |
排队响应头(在渲染时发送) |
%res->type |
响应的 Content-Type |
%res->text($body) / %res->json(...) / %res->xml($body) |
设置主体(以及 json/xml 的类型);可链式调用 |
%res->render($code = null) |
发送状态、头部和主体;标记响应完成 |
%res->streaming |
true 切换 apply() 为每个命令立即刷新(参见 WebSocket 章节) |
%res->status, %res->done |
状态码;输出是否已发送 |
output($content, $filename = null, $attachment = null, $file = null, $code = null, $type = null) 是用于文件、二进制大对象和带状态的 JSON 的响应函数:它提供一个文件(按名称的 mime,可选的 attachment),或者当 $content 是数组时返回 JSON(output(['id' => $id], code: 201),output(['error' => 'not found'], code: 404));type 会覆盖预编码字符串主体的内容类型。view()/apply()/output()/error()/location() 是应用代码使用的响应函数;上面的 %res->json/text/xml/render 成员是它们构建的低级原语,用于少见的手动组装响应(自定义头部,特殊内容类型)。不要将它们包装在每个应用的 jsonOut()/respond() 辅助函数中。
课程。
die($content)看起来像是“发送响应”,但它绕过了render():排队的头部(包括 Content-Type)永远不会离开服务器,并且在工作模式下die()会终止整个工作进程。这个网站以text/html的形式提供其机器可读的端点已经有几周了。始终以output(...)、view()、apply()、location()或显式的%res->...->render()结束。
运行时错误会记录在 data/errors.json 中,包含消息、源映射的 .phlo 文件和行号、主机、计数器以及最后一次发生的时间(按主机 + 位置 + 消息去重)。可以通过 reflect::errors [limit] 或在 Phlo Control Center 中读取它们。