mtphp 文档

视图模板

源文件 app/Views/*.tpl,首次渲染时编译为纯 PHP 缓存到 runtime/views/*.php,之后直接 include(零运行时解析开销),源文件更新自动重编译。

{{ $title }}                       <!-- 自动 htmlspecialchars 转义,防 XSS -->
{!! $rawHtml !!}                   <!-- 原样输出,不转义 -->
{{-- 这是注释,编译后完全移除,不会出现在 HTML 中 --}}

@if ($count > 0)
  <p>共 {{ $count }} 条</p>
@elseif ($count > 10)
  <p>很多条</p>
@else
  <p>暂无数据</p>
@endif

@foreach ($items as $it)
  <li>#{{ $loop->iteration }}/{{ $loop->count }} {{ $it['name'] }}</li>
@endforeach

@forelse ($items as $it)
  <li>{{ $it['name'] }}</li>
@empty
  <li>集合为空时走这里</li>
@endforelse

@switch ($status)
  @case('ok')   <p>正常</p>   @break
  @default      <p>未知</p>
@endswitch

@include('partial.footer', ['year' => 2026])   <!-- 内联渲染子模板,可追加数据 -->

设计取向(重要):模板引擎追求的是调用简单(指令少、语义直观),但功能向主流框架看齐(Blade 风格,思想借鉴、独立实现)。下面 §9.2 给出完整指令速查;真正用到时再查即可,日常 90% 场景只需要 @extends/@section/@yield 与 {{ }}。

字面量 @ 转义:正文里若想原样显示 @foreach、@if 这类字样(而非当成指令),写成 @@foreach、@@if 即可。@@ 在编译结束后会被还原成单个 @,且不会被解析为指令。这一规则同样适用于注释、组件、资源栈等所有指令所在的文本位置。

// 控制器中
return view('home', ['title' => 'mtphp', 'items' => $list]);

9.1 布局模板(@extends / @section / @yield / @parent)

多页共用同一套页面骨架(头部、导航、页脚)时,用布局模板避免重复。思路:写一个布局用 @yield 占位,子页面用 @extends 继承它、用 @section 填内容。

布局 app/Views/layouts/app.tpl(骨架 + 占位):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <title>@yield('title', 'mtphp 应用')</title>   <!-- 第二参数是默认内容 -->
</head>
<body>
    <header><h1>mtphp 站点</h1></header>
    <aside>@yield('sidebar', '默认侧边栏')</aside>    <!-- 子页可覆盖/追加 -->
    <main>@yield('content')</main>                   <!-- 主体内容占位 -->
    <footer>© 武汉麦麦心选网络科技有限公司 · @yield('year', '2026')</footer>
</body>
</html>

子页面 app/Views/home.tpl(继承布局、填充区块):

@extends('layouts.app')                 <!-- 继承上面的布局(点号等价于目录斜杠) -->

@section('title')
mtphp 首页
@endsection

@section('content')
    <h2>{{ $title }}</h2>
    <p>本页内容由 @section('content') 定义,布局用 @yield('content') 输出。</p>
@endsection

控制器照常 return view('home', $data) 即可,框架会自动完成「收集子页区块 → 渲染布局并注入」的两遍渲染。

@parent(在布局默认内容上追加):若子页区块里写 @parent,会被替换成布局同名 @yield 的默认内容,便于“保留默认 + 追加”:

@section('sidebar')
@parent                                       <!-- 先输出布局 sidebar 默认内容 -->
<ul><li>子模板追加的菜单项 A</li></ul>          <!-- 再追加本页内容 -->
@endsection

说明与限制(这里的“简单”指调用/使用简单,而功能对标主流框架——指令少、语义直观,但能力向 Blade 风格看齐(思想借鉴、独立实现),详见 §9.2): - 区块语法仅支持块形式 @section('name') ... @endsection;不支持内联 @section('name','默认')。 - 当前支持一层继承(子页 → 布局);布局本身不再二次 @extends。 - 布局默认内容(@yield 第二参数)里不要出现字面量 @parent,否则会被原样输出。 - 模板名里的 . 等价于目录分隔符:layouts.app → app/Views/layouts/app.tpl。

9.2 指令速查(Blade 风格)

下面列出模板引擎支持的全部指令。日常大多数页面只需用到 {{ }} 与 §9.1 的布局指令;其余指令在需要时查阅即可。

输出(转义 / 原样)

指令作用
{{ $var }}输出变量,自动 htmlspecialchars 转义(ENT_QUOTES),防 XSS
{!! $var !!}原样输出,不转义(仅用于受信任的 HTML)
{{-- 注释 --}}Blade 风格注释,编译后彻底移除,不出现在产物中

条件 / 分支

指令作用
@if / @elseif / @else / @endif条件分支
@unless (expr) ... @endunless条件取反(if (!expr))
@isset($v) ... @endisset变量是否存在
@empty($v) ... @endempty变量是否为空
@switch($v) / @case(expr) / @default / @endswitch多分支(注意:@case/@default 行不要缩进也能正常工作,引擎已处理)

循环

指令作用
@foreach ($items as $it) ... @endforeach遍历,自动注入 $loop 循环变量
@forelse ($items as $it) ... @empty ... @endforelse集合为空时走 @empty 分支
@for (...) ... @endfor计数循环
@while (expr) ... @endwhile条件循环
@continue / @break循环控制;支持条件写法 @continue($i>3)、@break($i>3)

$loop 循环变量(Blade 风格):$loop->index(从 0)、$loop->iteration(从 1)、$loop->count(总数)、$loop->first/$loop->last、$loop->even/$loop->odd、$loop->remaining(剩余项数)、$loop->depth(嵌套深度)、$loop->parent(外层 $loop)。

片段 / 组件

指令作用
@include('tpl'[, $data])内联渲染子模板,自动继承当前数据,可用第二参数追加
@includeIf('tpl') / @includeWhen($cond,'tpl') / @includeUnless($cond,'tpl')条件包含
@includeFirst(['a','b'])依次尝试,渲染第一个存在的模板
@each('row', $items, 'item'[, 'emptyTpl'])一行遍历集合;空集合走空模板
@component('comp'[, $props]) ... @endcomponent渲染组件视图
@slot('name') ... @endslot在 @component 内定义具名插槽(未命名的默认插槽即 $slot)
@props(['a' => 1])组件内声明带默认值的属性(仅当未传入时才用默认值)

资源栈(注入 CSS / JS)

指令作用
@push('scripts') ... @endpush向某资源栈追加内容
@prepend('scripts') ... @endprepend向某资源栈前插内容
@stack('scripts')输出该栈累积的全部内容(通常放在 <head> 或 </body> 前)

布局辅助(运行期判断区块)

指令作用
@hasSection('name') ... @else ... @endif子模板是否定义了某区块
@sectionMissing('name') ... @else ... @endif子模板是否未定义某区块

输出助手

指令作用
@json($data)输出 json_encode(JSON_UNESCAPED_UNICODE / 不转义斜杠)
@checked($cond) / @selected($cond) / @disabled($cond)条件输出 checked/selected/disabled 属性
@class(['a' => $cond, 'b'])条件拼接 class:['a'=>true,'b'] → a b;['active'=>false,'base'] → base

其它

指令作用
@php ... @endphp原样 PHP 块(可多行,也可内联 @php echo $x; @endphp)
@verbatim ... @endverbatim原样保留块内 {{ }} 与 @ 指令不编译,适合放 Vue / Angular 等前端模板
@@指令名字面量转义:正文想显示 @if 字样时写 @@if,编译后还原为 @if 且不被解析

布局相关指令 @extends / @section / @yield / @parent 见 §9.1。