vendor\laravel\framework\src\Illuminate\View
是视图模块所在的文件夹,如未说明类所在文件位置则指此文件夹。php
在使用视图相关的功能以前是须要作些准备的,准备天然是在服务提供者类运行的(在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
这个时候咱们已经能够看出Factory
是视图模块重要的类了,由于Laravel会从容器中取出view.engine.resolver, view.finder, events(这个类是其余地方注入到容器中的)中的对象做为参数传递给Factory
,而php和blade虽然并无注入到容器,倒是做为EngineResolver
的属性$resolvers
的值的。
FactoryFactoryEngineResolver$resolvers
上一步骤只是作了些视图运行前的准备,而并无真的运行视图的功能,通常运行是从view()
开始的,这是一个全局的方法,这个方法是定义在vendor\laravel\framework\src\Illuminate\Foundation\helpers.php
中的,这里其实调用了Factory
的make()
,这个方法其实主要是对传入的参数作处理并用这些参数初始化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()
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*/ ?>