0

0

Laravel 模板引擎(Blade)原理简析

php中文网

php中文网

发布时间:2016-06-20 12:45:47

|

1587人浏览过

|

来源于php中文网

原创

上次提到过,模板引擎一般是要做三件事情:

  • 变量值的输出(echo)

  • 条件判断和循环(if ... else、for、foreach、while)

  • 引入或继承其他文件

  • 现在就来看看 Laravel 的模板引擎是如何来处理这三件事情的。我是在 Laravel 5.1 的实现上来写这篇文章的。

    1. 视图解析流程

    Laravel 的 View 部分是内置了两套输出系统:直接输出和使用 Blade 引擎“编译”后输出,默认情况下它们通过文件名后缀来选择:.blade.php 后缀的认为是模板视图文件,其他的 .php 文件按照 PHP 本身的方式执行。虽然 Blade 模板文件中也可以随意嵌入 PHP 代码,但如果并没有使用,系统还去进行语法解析和替换也是没有必要的,这样可以提高效率。

    在使用 View 组件输出时,不管是调用 helpers 中提供的 view 函数还是使用 Facades 提供静态接口 View::make(),实际上执行的都是 Illuminate\View\Factory 中的 make 方法。以此为入口,很容易就能知道视图解析输出的流程:

  • 查找视图文件;

  • 根据文件名后缀从 Container 中取出响应的引擎;

  • 加载视图文件或编译后加载编译后的文件执行,同时将需要解析的数据暴露在视图文件环境中。

  • Factory 中的一些方法完成了以上第一步的过程,文件查找是调用的 FileViewFinder,其中使用了一些 Illuminate\Filesystem\Filesystem 中的方法,这个类中还有一些方法是跟 events 相关的,这里就忽略不表了。

    在以上步骤中,如果中获取到的视图文件是需要“编译”的,引擎会调用 “Blade 编译器”将原视图进行“编译”并保存在 cache 目录中然后加载输出。下次调用时如果发现源文件并没有被修改过就不再重新编译而是直接获取缓存文件并输出。

    CompilerEngine 调用的编译器是 CompilerInterface 接口的实现,默认情况下也就只有 BladeCompiler(如果不知道解析器是如何注入的,你需要去了解 Laravel 的服务容器,这里就不细表)。

    2. Blade 引擎

    接下来就是本文的重点:Blade 是如何“编译”的。我一直给“编译”两个字加引号,因为这显然不是真正意义上的代码编译的过程,只是一些正则替换的过程。

    我们知道 Laravel 的模板引擎是很简洁的,使用时并不需要掌握太多东西,基本上只需要知道以下两点:

  • {{ 与 }} 之间是要输出的内容,也有扩展的两个方法 {{{ ... }}} 和 {!! .. !!} 分别用于转义输出和不转义输出,5.0 以后的版本中 {{ ... }} 之间的默认情况下也是转义处处的;

  • @ 符号开头的都是指令,包括 PHP 本身有的 if else foreach 以及扩展的 include yield stop 等等;

  • 而 Blade 对于解析的处理实际上是分了四种情况:

  • Extensions -> 扩展部分

  • Statements -> 语句块(就是 @ 开头的指令)

  • Comments -> 注释部分({{-- ... --}} 的写法,解析之后是 PHP 的注释而不是 HTML的注释)

  • Echos -> 输出

  • 在解析(解析是在 cache 不存在的情况下)过程中,Blade 会先使用 token_get_all 函数获取到视图文件中的被 PHP 解释器认为是 HTML(T_INLINE_HTML)的部分,然后依次进行以上四种情况的解析。

    扩展部分是调用用户自定义的编译器解析字符串。BladeCompiler 中提供了的 extend 方法来添加可扩展。

    注释部分也很简单,就是将 {{-- ... --}} 替换成

    输出部分提供了三个方法,分别对应上文提到的三种情况:

  • compileRawEchos -> 输出未经转义的内容 ({!! ... !!})

  • compileEscapedEchos -> 输出转义之后的内容 ({{{ ... }}})

  • compileRegularEchos -> 正常输出 ({{ ... }})

  • 默认情况下经过字符替换之后 compileEscapedEchos 和 compileRegularEchos 的函数体其实是完全一样的,在输出的时候都是调用一个 e() 的辅助函数来输出:

    toHtml();        }        return htmlentities($value, ENT_QUOTES, 'UTF-8', false);    }

    这貌似是 5.0 之后的版本才改的,之前的版本里 compileRegularEchos 执行的是 compileRawEchos 的行为。不过两个函数还是有一个区别:compileRegularEchos 的转义函数是可以通过 setEchoFormat 自定义的(只是默认是 e()),但是 compileEscapedEchos 不允许自定义。

    echo 后的内容也是经过正则替换的:

       

    从正则表达式中可以看出来输出提供了一个 or 的关键字,$a or $b 的写法会被替换成 isset($a) ? $a : $b。

    语句块部分可以分成三种情况:

  • 和 PHP 本身一样的 if else foreach 以及扩展的 unless 等流程和循环控制的关键字;

  • include yield 等模板文件引入、内容替换的部分;

  • lang choice can 等涉及到 Laravel 其他组件的功能性关键字。

  • 第一种情况是很简单的替换过程,本身 PHP 为了在 HMTL 和 PHP 混合书写方便就提供了 if foreach 等几个关键字使用冒号和 endif 等关键字代替大括号来控制流程的方法。

    第二种情况稍微复杂一点,比如下面的函数:

    yieldContent{$expression}; ?>";    }

    解析之后的语句是调用了一个名为 $_env 的实例中的方法。这个实例其实就是 Illuminate\View\Factory 的实例:

    Factory 的构造函数:

    share('__env', $this);    }

    Illuminate\View\View 中:

    engine->get($this->path, $this->gatherData());    }    /**     * Get the data bound to the view instance.     *     * @return array     */    protected function gatherData()    {        $data = array_merge($this->factory->getShared(), $this->data);        ...        return $data;    }

    由此也可以看出 each yield 等指令的实现也是在 Factory 中,分别对应的是 renderEach yieldContent 等。

    所以文件引入等指令的实现方式就是:在主视图输出的时候,通过注入的 $__env 来重复调用 Factory 中的 make 方法来输出引入的文件。

    至于 lang 等关键字,替换后就是使用 app() 函数来调用 Laravel 的其他组件。此外 Blade 还提供了 inject 关键字来调用任何你想使用的组件。

    除了以上这些,你还可以通过 directive 方法来增加一些自定义指令。

    compileStatements 方法中最后进行正则替换的正则表达式看起来比较复杂:

    /\B@(\w+)([ \t]*)(\( ( (?>[^()]+) | (?3) )* \))?/x

    这是因为正则后面的一部分实现了递归模式来匹配语句块中括号的数量。

    3. 后话

    通过以上的分析可以看出来 Laravel 的视图组件还是十分简洁的,同时也不失灵活性和可扩展性。如果有兴趣的话,也可以实现一个自己的模板解析引擎。

    如果你想在其他项目中使用 Blade 引擎,通过 Composer 安装下来之后会发现还有 Container、Events 等部分,这和 Laravel 本身有关。

    为了能够在任何地方使用 Blade,我把它核心的部分提取了出来,去掉了其他组件的依赖,也不再依赖文件扩展名来选择引擎:

    项目地址:https://github.com/XiaoLer/blade

    此外也通过这个提取之后的版本做了一个 yii2 能够使用的版本:https://github.com/XiaoLer/yii2-blade。在之前尝试的版本中直接使用 Laravel 的 View 组件并不灵活,现在感觉好多了。

    个人博客原文:http://0x1.im/blog/laravel/laravel-blade-engine.html

    热门AI工具

    更多
    DeepSeek
    DeepSeek

    幻方量化公司旗下的开源大模型平台

    豆包大模型
    豆包大模型

    字节跳动自主研发的一系列大型语言模型

    通义千问
    通义千问

    阿里巴巴推出的全能AI助手

    腾讯元宝
    腾讯元宝

    腾讯混元平台推出的AI助手

    文心一言
    文心一言

    文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

    讯飞写作
    讯飞写作

    基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

    即梦AI
    即梦AI

    一站式AI创作平台,免费AI图片和视频生成。

    ChatGPT
    ChatGPT

    最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

    相关专题

    更多
    2026春节习俗大全
    2026春节习俗大全

    本专题整合了2026春节习俗大全,阅读专题下面的文章了解更多详细内容。

    68

    2026.02.11

    Yandex网页版官方入口使用指南_国际版与俄罗斯版访问方法解析
    Yandex网页版官方入口使用指南_国际版与俄罗斯版访问方法解析

    本专题全面整理了Yandex搜索引擎的官方入口信息,涵盖国际版与俄罗斯版官网访问方式、网页版直达入口及免登录使用说明,帮助用户快速、安全地进入Yandex官网,高效使用其搜索与相关服务。

    200

    2026.02.11

    虫虫漫画网页版入口与免费阅读指南_正版漫画全集在线查看方法
    虫虫漫画网页版入口与免费阅读指南_正版漫画全集在线查看方法

    本专题系统整理了虫虫漫画官网及网页版最新入口,涵盖免登录观看、正版漫画全集在线阅读方式,并汇总稳定可用的访问渠道,帮助用户快速找到虫虫漫画官方页面,轻松在线阅读各类热门漫画内容。

    40

    2026.02.11

    Docker容器化部署与DevOps实践
    Docker容器化部署与DevOps实践

    本专题面向后端与运维开发者,系统讲解 Docker 容器化技术在实际项目中的应用。内容涵盖 Docker 镜像构建、容器运行机制、Docker Compose 多服务编排,以及在 DevOps 流程中的持续集成与持续部署实践。通过真实场景演示,帮助开发者实现应用的快速部署、环境一致性与运维自动化。

    4

    2026.02.11

    Rust异步编程与Tokio运行时实战
    Rust异步编程与Tokio运行时实战

    本专题聚焦 Rust 语言的异步编程模型,深入讲解 async/await 机制与 Tokio 运行时的核心原理。内容包括异步任务调度、Future 执行模型、并发安全、网络 IO 编程以及高并发场景下的性能优化。通过实战示例,帮助开发者使用 Rust 构建高性能、低延迟的后端服务与网络应用。

    1

    2026.02.11

    Spring Boot企业级开发与MyBatis Plus实战
    Spring Boot企业级开发与MyBatis Plus实战

    本专题面向 Java 后端开发者,系统讲解如何基于 Spring Boot 与 MyBatis Plus 构建高效、规范的企业级应用。内容涵盖项目架构设计、数据访问层封装、通用 CRUD 实现、分页与条件查询、代码生成器以及常见性能优化方案。通过完整实战案例,帮助开发者提升后端开发效率,减少重复代码,快速交付稳定可维护的业务系统。

    6

    2026.02.11

    包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
    包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

    本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

    159

    2026.02.10

    MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法
    MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法

    本专题汇总了MC.JS官网入口和网页版快速畅玩方法,提供免安装访问、不同版本(1.8.8、1.12.8)在线体验指南,以及正版网页端操作说明,帮助玩家轻松进入MC.JS世界,实现即时畅玩与高效体验。

    89

    2026.02.10

    谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程
    谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程

    本专题汇总了谷歌邮箱网页版的最新登录入口和注册方法,详细提供官方账号快速访问方式、网页版操作教程及安全登录技巧,帮助用户轻松管理Gmail邮箱账户,实现高效、安全的邮箱使用体验。

    78

    2026.02.10

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    后盾网smaryt模板引擎视频教程
    后盾网smaryt模板引擎视频教程

    共14课时 | 2.6万人学习

    Smarty模板引擎(布尔教育)
    Smarty模板引擎(布尔教育)

    共12课时 | 2.3万人学习

    Smarty视频教程(传智播客)
    Smarty视频教程(传智播客)

    共23课时 | 5.2万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号