4: 语法与结构
Phlo 将 .phlo 源文件编译为普通的 PHP 类和生成的资产。语法类似于 PHP,但语句末尾没有分号。
4.1: 文件结构
一个 .phlo 文件可以包含顶级控制器代码和节点:
routefunctionpropstaticmethodview<style><script>
示例:
route both GET home => view($this)
prop title = 'Welcome'
view:
<h1>$this->title</h1>4.2: 语句和行解析器
语句在换行时结束,而不是在分号处结束:
$count = 1
if ($active) $count++
这有效是因为编译器在每一行的末尾附加一个 ;,并且仅在行明显继续时才会删除它。完整的规则集:
- 每一行的末尾都有一个
;。 - 当行以
(、[、{、}、,或.结尾时,该;会被删除。这些是隐式续行:一个开括号、参数列表中的尾随逗号,或在.后断开的连接。 - 以单个反斜杠
\结尾的行是显式续行:解析器会删除反斜杠和分号,并将该行与下一行连接。对于不属于隐式集合的任何内容,请使用此方法,例如多行三元表达式:
$label = $visitors === 1 \
? 'visitor' \
: 'visitors'
- 空行永远不会有
;。
心理模型:完全停止考虑分号。只问“我的语句在这一行完成了吗?”如果没有,请用其中一个 ( [ { , . 结束该行(这在大多数多行代码中自然发生)或使用显式的 \。
没有隐式或显式续行的情况下,每一行都成为自己的语句。这就是为什么在多行调用中,每个参数行必须以逗号结束,包括最后一个:
apply (
title: 'Done',
main: '<p>Ready</p>',
)
课程。 文件级节点解析器通过计数括号来跟踪多行节点主体,而不是方括号。多行
prop x => [ ... ]在其第一行结束节点,剩余行变成孤立的控制器代码(Controller must be in one place)。用括号打开多行节点主体:prop x => arr(...)或prop x => array_merge(...)。
4.3: 控制器代码
顶层代码如果不是节点,则成为生成类的控制器代码。该代码在实例首次被检索时运行。
prop ready = false
$this->ready = true
使用控制器代码进行轻量级初始化。将请求逻辑放在 routes 和 methods 中。
4.4: 实例
使用 %name 通过实例管理器检索 Phlo 对象:
%payload->name
%session->user
%creds->mysql->database
实例是懒加载的,然后在请求中重用。
课程。 编译器在
.phlo文件中的每个地方重写%name,包括字符串字面量内。试图在代码示例中打印字面文本%session的页面向其访问者发送了phlo('session')。必须保持原样的示例代码应放在运行时加载的外部文件中(.txt,.md),而不是在.phlo字符串字面量中。
4.5: Props
静态属性:
prop title = 'App'
计算属性:
prop fullName => $this->first.' '.$this->last
计算属性作为 getter 生成,可以作为属性读取:
$this->fullName4.6: 方法
单行方法:
method label($value) => ucfirst($value)
多行方法:
method label($value){
if (!$value) return void
return ucfirst($value)
}4.7: 函数
您可以使用 function 定义全局函数:
function initials($name){
return strtoupper(substr($name, 0, 1))
}
请谨慎使用。对于应用代码,常规应用类通常更好;只有框架范围内的助手才应属于运行时资源。
4.8: 静态
静态值:
static table = 'users'
静态方法:
static label($value) => ucfirst($value)
调用:
user::label('jordi')4.9: 字符串和运算符
字符串和运算符遵循 PHP:
$name = 'Jordi'
$title = "Hello $name"
$active = $count > 0 && !$archived
当意图明确时,使用 void 表示空字符串。
4.10: 命名参数
命名参数的工作方式与 PHP 相同,并保持调用的可读性:
%DB->load (
table: 'users',
where: 'active=1',
order: 'name',
)4.11: 错误处理和 JSON 响应
error('message', $code = 500) 中止请求并返回状态。它抛出(不需要 return),引擎会根据请求进行渲染:
- 一个 async/SPA 请求会得到
apply(error: 'message')(phlo.js 会显示它); - JSON 上下文(调用的路由
%security->api,或者客户端发送了Accept: application/json)会得到一个 JSON 主体{"error": "message"}以及状态码; - 否则会返回 HTML 错误页面(当
debug: true时为完整调试页面,否则为最小页面)。
if (!$record) error('Record not found', 404)
客户端错误($code < 500)保留其消息;服务器错误(>= 500)保持通用("Error"),除非 debug: true,因此未捕获的异常内部信息默认不被暴露。
对于成功的 JSON 响应,使用 output($data, code:):数组会自动编码,code 设置状态。因此,JSON API 路由使用 output() 处理结果,使用 error() 处理失败,没有每个应用的响应包装。
debug: true(在 www/app.php 中设置)启用详细的调试输出;运行时错误会记录到 data/errors.json。