Laravel 视图模块运行流程

提示:

vendor\laravel\framework\src\Illuminate\View是视图模块所在的文件夹,如未说明类所在文件位置则指此文件夹。php

1. 服务提供者类注入相关类到容器

在使用视图相关的功能以前是须要作些准备的,准备天然是在服务提供者类运行的(在app\config.php的providers中定义了应用中的服务提供者类),从中咱们能够看出Illuminate\View\ViewServiceProvider::class指的就是ViewServiceProvider类,所以在ViewServiceProvider类中会注册一些须要用到的依赖到容器,注入名称和实例以下:laravel

view.engine.resolver  EngineResolver
    php               PhpEngine
    blade             CompilerEngine
blade.compiler        BladeCompiler
view.finder           FileViewFinder
view                  Factory
file
这个时候咱们已经能够看出Factory是视图模块重要的类了,由于Laravel会从容器中取出view.engine.resolver, view.finder, events(这个类是其余地方注入到容器中的)中的对象做为参数传递给Factory,而php和blade虽然并无注入到容器,倒是做为EngineResolver的属性$resolvers的值的。
FactoryFactoryEngineResolver$resolvers

2.开始使用视图

上一步骤只是作了些视图运行前的准备,而并无真的运行视图的功能,通常运行是从view()开始的,这是一个全局的方法,这个方法是定义在vendor\laravel\framework\src\Illuminate\Foundation\helpers.php中的,这里其实调用了Factorymake(),这个方法其实主要是对传入的参数作处理并用这些参数初始化View类,再返回View的实例。缓存



对的处理还涉及到和的处理,不理会这个咱们是知道视图其实返回的应该是字符串的才对。对象转字符串天然使用的是魔术方法,这里并不直接返回字符串,而是经过一系列的调用最终是在中返回,这里的engine是,即上面View实例化的时候传递的第二个参数(也是的实现),由于Laravel的视图文件的名称包含blade,因此实例化的是。事实上这和容器中名为view.engine.resolver的类实例有关,具体细节能够在中找。$this->callCreator($view = new View($this, $this->getEngineFromPath($path), $view, $path, $data)); return $view;ViewRouterResponse__toString()getContents()$this->engine->get()CompilerEngineEngineInterfaceCompilerEnginegetEngineFromPath()

3.模版的编译

CompilerEngine$compiler才是实际把视图文件转成字符串的主力。通常的$compiler的实例是BladeCompiler,这个就是把Blade语法(Blade是Laravel内置模版引擎的名字)转换成PHP语法的核心。app

无论上面的步骤如何的绕来绕去,把视图文件编译成字符串才是BladeCompiler类的主场功能,这个类才是真正的苦力工做者。BladeCompiler实现了CompilerInterface接口,这个接口真正工做是compile()compile()把视图文件编译成PHP的原生语法的字符串并写入到缓存目录的文件中,而getCompiledPath()根据视图文件的路径来获取编译后的文件的路径。ide

编译使用token_get_all()来进行语法的解析,当碰到PHP标记为T_INLINE_HTML(T_INLINE_HTML标记其实就是code没法直接解析成PHP而把这段code看成一段嵌套的HTML,这里通常就是指Blade语法的Code)的PHP标记时用对应的方法进行语法的替换,直到最终没有PHP标记为T_INLINE_HTML为止。this

没法直接编译的code分为4类,分别是扩展,语句,注释,输出,这个从$compilers中能够看出,咱们能够称$compilers为内部编译器,每一个内部编译器对应一个相应的解析方式,如注释编译器对应compileComments().net




这里就把Blade语法的code变成原生PHP语法的code了。 从中不难看出就是把Blade语法翻译成PHP原生语法的实现。固然这是最简单的内部编译器,像语句,输出内部编译器的实现就复杂的多,但只是实现复杂,涉及到正则的解析和不一样形式的语句的解析,原理仍是同样的。/** * Compile Blade comments into valid PHP. * * @param string $value * @return string */ protected function compileComments($value) { $pattern = sprintf('/%s--((.|\s)*?)--%s/', $this->contentTags[0], $this->contentTags[1]); return preg_replace($pattern, '<?php /*$1*/ ?>', $value); }{{-- This comment will not be present in the rendered HTML --}}<?php /*This comment will not be present in the rendered HTML*/ ?>
相关文章
相关标签/搜索