Tips:
vendor\laravel\framework\src\Illuminate\View
is the folder where the View module is located, such as the file location where the class is not indicated.
1. The service provider class injects related classes into the container
Before using view-related features, it is necessary to prepare for the nature of the service provider class (the app\config.php
service provider class in the application is defined in the providers), where we can see that the Illuminate\View\ViewServiceProvider::class
class is referred to ViewServiceProvider
, so ViewServiceProvider
Class will register some dependencies that need to be used to the container, injecting the name and instance as follows:
view.engine.resolver EngineResolver php PhpEngine blade CompilerEngineblade.compiler BladeCompilerview.finder FileViewFinderview Factory
这个时候我们已经可以看出Factory
是视图模块重要的类了,因为Laravel会从容器中取出view.engine.resolver, view.finder, events(这个类是其他地方注入到容器中的)中的对象作为参数传递给Factory
,而php和blade虽然并没有注入到容器,却是作为EngineResolver
的属性$resolvers
的值的。
2. Getting Started with views
The previous step is just to do some view before the preparation of the run, and does not really run the view function, the general run is from view()
the beginning, this is a global approach, this method is defined in vendor\laravel\framework\src\Illuminate\Foundation\helpers.php
the, here actually called Factory
make()
, This method is essentially to handle the parameters passed in and initialize the class with these parameters View
, and then return View
the instance.
$this->callCreator($view = new View($this, $this->getEngineFromPath($path), $view, $path, $data));return $view;
The handling of the pair View
also involves Router
and Response
handles, ignoring this we are aware that the view actually returns the string that should be the only pair. The object-to-string nature uses the Magic method __toString()
, which does not directly return a string, but is eventually returned through a series of calls, getContents()
$this->engine->get()
where the engine is the CompilerEngine
second parameter passed when the view was instantiated (also EngineInterface
implementation) because the name of the Laravel view file contains blade, so the instantiation is CompilerEngine
. In fact, this is related to the class instance named View.engine.resolver in the container, and the specifics can be getEngineFromPath()
found in.
3. Compiling the template
CompilerEngine
is the main force that $compiler
actually turns the view file into a string. A general $compiler
example of this is the BladeCompiler
conversion of blade syntax (Blade is the name of the Laravel built-in template engine) to the core of PHP syntax.
No matter how the above steps go around, compiling the view file into a string is the BladeCompiler
home function of the class, and this class is the real laborer. BladeCompiler
implements the CompilerInterface
interface, which really works by compile()
compile()
compiling the view file into PHP's native syntax string and writing it to the file in the cache directory, and obtaining the getCompiledPath()
path to the compiled file based on the path to the view file.
Compile use token_get_all()
to parse the syntax, when it comes to PHP tag T_INLINE_HTML
( T_INLINE_HTML
tag is actually code can not parse directly into PHP and the code as a nested HTML, here is generally referred to as the code of the blade syntax) PHP tags are replaced with a corresponding method of syntax until the PHP tag is finally marked T_INLINE_HTML
.
The code that cannot be compiled directly is divided into 4 classes, which are extensions, statements, annotations, outputs, as $compilers
can be seen from the inside, we can be called $compilers
internal compilers, each internal compiler corresponding to a corresponding parsing method, such as the comment compiler corresponds compileComments()
.
/** * 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 will change the code of the blade syntax {{-- This comment will not be present in the rendered HTML --}}
into the code of the native PHP syntax <?php /*This comment will not be present in the rendered HTML*/ ?>
. It is not difficult to see that the blade grammar is translated into PHP native syntax implementation. Of course, this is the simplest internal compiler, like statements, the implementation of the output of the internal compiler is more complex, but only the implementation of complex, involving regular parsing and the interpretation of different forms of statements, the principle is the same.
Laravel View Module Run flow