备注:纯手打的学习笔记,如有错误之处请指正,谢谢。希望大家学的开心!
定位
接上一章的内容,我们继续。
来到 bootstrap/app.php
发现了一段英文注释,翻译过来为:
/ *
| --------------------------------------------------------------------------
|创建应用程序
| --------------------------------------------------------------------------
|
|我们首先要做的是创建一个新的 laravel 应用实例
|作为“胶水”用于 laravel 的所有组件,并
|为系统结合各种零件的 IOC 容器。
|
* /
换句话说,把这个对象实例作为一个可依靠稳固的地基,来存放各种“建筑物(组件)”,So 地基= IOC 容器? 好复杂有木有,不管它了,读代码去吧,读代码就像聊天,得用心倾听别人的心声。
紧接着 new 了一个对象。
new Illuminate\Foundation\Application() 构造函数做了什么?对了,Application 类还传入了当前 laravel 根目录的地址这样一个参数。如 “D:\webSite\Laravel” 。
命名空间 Illuminate 的具体文件路径位于
Vendor/laravel/framework/src/Illuminate。
然后根据命名空间的顺序找到目录 Foundation,再找到文件 Application.php 打开即可。
打开文件,我又醉了,先是定义一个命名空间,接着各种 use,往下看,到这里:
class Application extends Container implements ApplicationContract, HttpKernelInterface
继承 Container 类,对应上面的use:use Illuminate\Container\Container; 并且要实现2个接口 ApplicationContract,HttpKernelInterface,
咱们先看看这个 Container 类到底是什么。
怎么找具体文件上面已经说过了,下面就直接略过,直接打开 Container.php。
Container 类
打开文件,第一反应又要去补知识了。
The ArrayAccess interface 数据访问接口,PHP5的一个新接口,接口提供访问对象数组。
需要实现四个方法:
abstract public boolean offsetExists ( mixed $offset )
abstract public mixed offsetGet ( mixed $offset )
abstract public void offsetSet ( mixed $offset , mixed $value )
abstract public void offsetUnset ( mixed $offset )
先不用懂这4个方法是什么意思,看看 Container 类怎么实现的就懂了。
当外部使用 isset() 函数时触发此方法,而方法内部则也是使用一个 isset 来判断返回一个 bool 值。这个 bindings 先不管,我们主要知道这个方法做了什么事情。
当外部尝试获取 $key 的时候,如 echo ,print_r,var_dump,赋值等。
就会触发此方法,而方法内部也是直接一个 reutrn,简单!
当外部尝试赋值的时候,则触发此方法。
此方法内部先进行一个 instanceof 判断 如果 value 参数不是一个闭包,则将 ·$value· 封装成一个闭包,而闭包函数的内部直接一个 return ,下面的 bind 不知道先不管。
当外部尝试使用 unset 函数的时候触发此方法,
图上的方法内部是一个 unset 函数,那些变量看不懂,先不管。
这就是 ArrayAccess,一个类实现它的4个方法,在不同操作时触发4个方法,知道这些就够了,具体调用的示例这里我没有举出来,PHP 官网有,请自行翻阅,锻炼下动手能力。
好吧继续往下看,又要开始补知识了,我去。
use ReflectionClass
use ReflectionMethod
use ReflectionFunction
use ReflectionParameter
这几个类又是什么鬼?崩溃!
Reflection =反射。 为了好理解些,我们就比喻成手术医生吧。
上面4个类都分别实现了 Refletor 这个接口,大家可以去看看这里:
然后这几个反射类里面有一些方法,就像动手术有不同的手法,要针对不同的病人实施不同的手法,而病人则需要给上面4个的构造函数传入一个参数(病人姓名),我们先来看看姓名为 “index” 的病人的就医过程。
具体代码如下:
namespace index;
use ReflectionClass;
use ReflectionMethod;
use ReflectionFunction;
use ReflectionParameter;
class index //病人姓名index
{
public function a(){}
}
function b($b,$c,$d)
{
}
/* ReflectionClass 示例
//找到医生ReflectionClass,医生问了姓名叫啥? 额... index\index
//那你有什么问题呢? 我想查查我会被人克隆吗?
//嗯,这个问题问的好。 我用我的isFinal手法给你查查看
//结果dump出一个false,你会被复制,因为你少了Final。
//就医结束
$a = new ReflectionClass('index\index');
var_dump($a->isFinal()); //false
*/
就是这么简单,其他高超的手法请自行PHP官网翻阅。
ReflectionMethod 针对类方法。
ReflectionFunction 针对普通函数
ReflectionParameter 针对函数的参数
具体代码演示如下:
/* ReflectionMethod 示例
$a = new ReflectionMethod('index\index','a');
var_dump($a->isAbstract()); //false
*/
/* ReflectionParameter 示例
$a = new ReflectionParameter('index\b',2);
var_dump($a->getName()); //string(1) "d"
*/
/* ReflectionFunction 示例
$a = new ReflectionFunction('index\b');
var_dump($a->getParameters());
array(3) {
[0]=>
&object(ReflectionParameter)#2 (1) {
["name"]=>
string(1) "b"
}
[1]=>
&object(ReflectionParameter)#3 (1) {
["name"]=>
string(1) "c"
}
[2]=>
&object(ReflectionParameter)#4 (1) {
["name"]=>
string(1) "d"
}
}
*/
好了,相信聪明的你应该知道反射了,继续看代码呗。
Use InvalidArgumentException 这个比较简单 ,请自行百度。
然后看到 Container 类还实现这个接口 ContainerContract。
对应 use Illuminate\Contracts\Container\Container as ContainerContract;
提示:Contracts 翻译“合同、契约”。
接口里面的方法有兴趣可自行查看,我们主要看 Container 的实现这些方法的细节。
最后我们简述下 Contracts 作为本章结束语:
我的理解是一系列组件服务的接口集合,好处?松耦合,有多松?怎么松?我也是菜鸟不要问我,以后咱们读代码自然会了解他的好处。
请关注 Laravel 执行流程(二)Container 类(下)
未完待续。。。。。