Laravel学习教程之View模块详解


Posted in PHP onSeptember 18, 2017

前言

本文主要是给大家介绍了关于Laravel中View模块的相关资料,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

本文是基于Laravel 5.4版本的路由模块代码进行分析书写;

文件结构

View模块的文件格局及功能如下图所示:

Laravel学习教程之View模块详解

视图化呈现时的大概流程:

1、通过view()方法的调用,开始视图的呈现;

2、首先,查找视图文件;

(1)依次遍历路径,如果文件名带命名空间(也就是::之前的部分),则采用命名空间对应注册的路径数组,否则采用全局路径数组(在Illuminate\View\FileViewFinder类中的paths变量);

(2)结合当前路径,文件名,后缀名(默认顺序是blade.php、php、css),判断文件是否存在;

(3)如果文件不存在,报异常:对应的view文件不存在;如果文件存在,则根据后缀名调用对应的引擎进行解析;

3、如果是css后缀,采用file引擎,核心调用方法是file_get_contents;

4、如果是php后缀,采用php引擎,核心调用方法是

ob_start();
include $__path;
ob_get_clean();

5、如果是blade.php后缀,采用blade引擎;

这个引擎会主动作缓存处理,如果缓存文件未过期,则直接调用缓存文件,否则重新编译,并通过sha1生成缓存文件(位于storage/framework/views目录下);

Blade 引擎编译

Blade引擎对文件的编译,是通过大量的正则匹配和替换实现的;

protected $compilers = [ 
 'Comments', // 注释部分
 'Extensions', // 扩展部分
 'Statements', // 语句块 (@ 开头的指令)
 'Echos',  // 输出
];

protected function parseToken($token) {
 list($id, $content) = $token;
 
 if ($id == T_INLINE_HTML) {
  foreach ($this->compilers as $type) {
   $content = $this->{"compile{$type}"}($content);
  }
 }
}

在解析的过程中,Blade会先使用token_get_all函数获取视图文件中的被PHP解释器认为是HTML(T_INLINE_HTML)的部分,然后依次进行Comments、Extensions、Statements 和 Echos部分的正则替换;

注释部分

核心代码如下,将注释符号“{{-- --}}”包裹的代码替换为空字符串;

preg_replace("/{{--(.*?)--}}/s", '', $value);

扩展部分

通过extend方法向BladeCompiler添加自定义处理的回调函数,对模板内容进行自定义的文本匹配替换;

核心代码在Illuminate\View\BladeCompiler文件中,如下:

// 自定义的文本替换扩展 数组
protected $extensions = [];

protected function compileExtensions($value) {
 foreach ($this->extensions as $compiler) {
  $value = call_user_func($compiler, $value, $this);
 }
 
 return $value;
}

指令替换

这部分就是将类似@if这种框架自带的指令和通过directive方法注册的指令进行文本替换;

框架提供的指令有以下十部分:

  • View\Compilers\Concerns\CompilesAuthorizations: 权限检查
    指令包括:@can、@cannot、@elsecan、@elsecannot、@endcan、@endcannot
  • Concerns\CompilesComponents:与组件、插槽相关
    指令包括:@component、@endcomponent、@slot、@endslot
  • Concerns\CompilesConditionals:与判断语句相关
    指令包括:@if、@unless、@else、@elseif、@endif、@endunless、@isset、@endisset、@hassection
  • Concerns\CompilesIncludes:嵌入文件
    指令包括:@each、@include、@includeif、@includewhen
  • Concerns\CompilesInjections:服务注入
    指令包括:@inject
  • Concerns\CompilesLayouts:和布局相关
    指令包括:@extends、@section、@parent、@yield、@show、@append、@overwrite、@stop、@endsection
  • Concerns\CompilesLoops:与循环相关
    指令包括:@forelse、@empty、@endforelse、@endempty、@for、@foreach、@break、@continue、@endfor、@endforeach、@while、@endwhile
  • Concerns\CompilesRawPhp:与原生PHP语句相关
    指令包括:@php、 @endphp、 @unset
  • Concerns\CompilesStacks:和堆栈相关
    指令包括:@stack、@push、@endpush、@prepend、@endprepend
  • Concerns\CompilesTranslations:与本地化翻译相关
    指令包括:@lang、@endlang、@choice

Echo 替换

echo输出是针对{!! !!}、{{ }}、{{{ }}}三种括号进行正则替换;

  • {!! !!}输出未转义字符,用于输出原生带html标签的值;
  • {{ }}正常输出,支持三目运算符替换;
  • {{{ }}}输出转义字符,支持三目运算符替换;

三目运算符替换是指:{{ $a ?: "默认值" }} (或者 {{$a or "默认值"}}) 换成 {{ isset($a) ? $a : "默认值"}}

参考文章

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

Laravel 5.4 文档 前端 —— Blade模板

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

PHP 相关文章推荐
一个从别的网站抓取信息的例子(域名查询)
Oct 09 PHP
PHP之变量、常量学习笔记
Mar 27 PHP
php自定义函数之递归删除文件及目录
Aug 08 PHP
从零开始学YII2框架(四)扩展插件yii2-kartikgii
Aug 20 PHP
PHP屏蔽过滤指定关键字的方法
Nov 03 PHP
PHP中的Session对象如何使用
Sep 25 PHP
PHP验证码生成原理和实现
Jan 24 PHP
全面解析PHP验证码的实现原理 附php验证码小案例
Aug 17 PHP
PHP通过引用传递参数用法分析
Dec 01 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
Jun 17 PHP
thinkphp5.0自定义验证规则使用方法
Nov 16 PHP
PHP扩展Swoole实现实时异步任务队列示例
Apr 13 PHP
php制作圆形用户头像的实例_自定义封装类源代码
Sep 18 #PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
Sep 17 #PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
Sep 16 #PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
Sep 16 #PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
Sep 16 #PHP
PHP环形链表实现方法示例
Sep 15 #PHP
PHP实现的链式队列结构示例
Sep 15 #PHP
You might like
php类自动装载、链式操作、魔术方法实现代码
2017/07/23 PHP
tp5.1 框架数据库高级查询技巧实例总结
2020/05/25 PHP
IE 下的只读 innerHTML
2009/08/21 Javascript
Javascript图像处理—为矩阵添加常用方法
2012/12/27 Javascript
用js来获取上传的文件名纯粹是为了美化而用
2013/10/23 Javascript
js单例模式详解实例
2013/11/21 Javascript
jquery实现个人中心导航菜单效果和美观都非常不错
2014/09/02 Javascript
js字符串完全替换函数分享
2014/12/03 Javascript
js判断子窗体是否关闭的方法
2015/08/11 Javascript
浅析AngularJs HTTP响应拦截器
2015/12/28 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
Javascript之Number对象介绍
2016/06/07 Javascript
js获取form表单所有数据的简单方法
2016/08/18 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
利用Ionic2 + angular4实现一个地区选择组件
2017/07/27 Javascript
vue实现商城上货组件简易版
2017/11/27 Javascript
JS执行控制之节流模式实例分析
2018/12/21 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
2019/09/11 Javascript
解决layer 关闭当前弹窗 关闭遮罩层 input值获取不到的问题
2019/09/25 Javascript
React生命周期原理与用法踩坑笔记
2020/04/28 Javascript
[01:27:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第一场 1月24日
2021/03/11 DOTA
python操作xml文件示例
2014/04/07 Python
Python实现比较两个文件夹中代码变化的方法
2015/07/10 Python
使用apidocJs快速生成在线文档的实例讲解
2018/02/07 Python
Python3操作YAML文件格式方法解析
2020/04/10 Python
python 字典item与iteritems的区别详解
2020/04/25 Python
将pycharm配置为matlab或者spyder的用法说明
2020/06/08 Python
python获取本周、上周、本月、上月及本季的时间代码实例
2020/09/08 Python
咖啡为什么会有酸味?你喝到的咖啡為什麼是酸的?
2021/03/17 冲泡冲煮
HTML5 本地存储和内容按需加载的思路和方法
2011/04/07 HTML / CSS
财务会计专业个人求职信范本
2014/01/08 职场文书
治庸问责心得体会
2014/09/12 职场文书
大学副班长竞选稿
2015/11/21 职场文书
《乌鸦喝水》教学反思
2016/02/19 职场文书
一篇文章带你学习Mybatis-Plus(新手入门)
2021/08/02 Java/Android
Mysql中一千万条数据怎么快速查询
2021/12/06 MySQL