Laravel框架运行机制(一)全局基本加载逻辑流程及 php使用数组索引方式访问对象ArrayAccess(数组式访问)接口

一、Laravel框架运行机制(一)全局基本加载逻辑流程-php

    这是Laravel框架的入口文件,pubic/index.php的代码,很简单,分了四个部分:

//加载laravel框架的autoload机制
require __DIR__.'/../bootstrap/autoload.php';

//取得app实例
$app = require_once __DIR__.'/../bootstrap/app.php';

//执行app,生成输出内容
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

//输出
$response->send();
$kernel->terminate($request, $response);

    首先加载larave根目录下bootstrap驱动里的autoload.php;这个文件引用后就是部署好对整个vendor的自动加载机制。实现后面根据命名名空间自动调用到vendor里的对应类。

    然后执行取得app:Illuminate\Foundation\Application的实例;对APP的初始化。

    然后生成$kernel,传入的是Illuminate\Contracts\Http\Kernel,但经过laravel的容器处理,生成的是App\Http\Kernel的核心处理类实例,laravel的容器Container维护着一套绑定关系bindings;在类文件Illuminate\Container\Container的$bindings属性值:下是 Illuminate\Container\Container对传来的Illuminate\Contracts\Http\Kernel的判断:

    而bindings的值里即存在对应的concrete值,这里就是laravel里到处可见的闭包函数的使用,如下图:

      所以传入Illuminate\Contracts\Http\Kernel后,最后返回实例化的App\Http\Kernel对象,实例化App\Http\Kernel的时又去查laravel的ClassMap如下图:

      最后就调到了应用目录下的app/Http/Kernel,而此类继承自类:use Illuminate\Foundation\Http\Kernel as HttpKernel;HttpKernel  里的handle方法对路由进行分析、处理请求并返回Pipeline类的处理结果,实际是 Illuminate\Http\Response类的实例化对象。

      上面的这步$request = Illuminate\Http\Request::capture(),是分析请求的所有参数,包括get/post/cookies以及server数据等。这步就是响应的核心,即传入所有入参,执行请求处理。

    程序执行到第三步,此时实际页面已经响应输出内容了,但laravel框架不知道是怎么回事,后面才执行$response->send();,而$response->send();这句代码是输出了很多header参数,我不认为这是laravel有意这样做,因为这看起来很无语。

      $response->send();一看就是要响应输出,然而laravel框架把这句和后面的那句代码注释掉,页面已经响应输出结果了。按这句话的本意逻辑,前面的handle只是处理请求,并不输出,要输出的结果已经入response对象了,再调用$response->send();输出。

    最后的这句$kernel->terminate($request, $response);对一些中间件进行了再处理。未再细看,laravel里的很多对象都特别特别地大,打印出来后根本没法看。第一篇就写这么多。

二、Php使用数组索引的方式访问对象-ArrayAccess(数组式访问)接口

     如果你没有接触过对象的数组式访问,你肯定不会想到对象也可以使用数组的方式来访问(对象不被转化成数组),因为类和对象是PHP里的两个类型,我们已经习惯了使用->访问对象,而使用索引[]来访问数组。于是对于一个对象,我们能说这样访问呢?如下:

//php数组式访问对象
class Testobj
{   
    public $testUnit = '-first';
}
$test = new Testobj();
echo $test['testUnit'];

    上面的代码肯定会报一个致命错误:Fatal error: Uncaught Error: Cannot use object of type Testobj as array in D:\Htdocs\phpinfo.php on line 9 

    但是PHP里确实可以实现使用数组的方式来访问对象。PHP自带有一个ArrayAccess(数组式访问)接口,所有的对象只要实现这个接口就可以使用数组的方式来访问对象,

interface ArrayAccess {
    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 )
}

ArrayAccess有四个方法,因此实现它的类必须重写这四个方法,如下PHP代码:

//php数组式访问对象
class Test implements ArrayAccess
{
    public $testUnit = '-first';
    
    public function getUnit()
    {
        return 'testunit';
    }

    public function offsetExists ($offset)
    {
        echo 1,__METHOD__;
    }
 
    public function offsetGet ($offset)
    {
        echo 2,__METHOD__."   ";
        if(isset($this->$offset)) return $this->$offset;
        elseif(method_exists($this, $offset)) return $this->$offset();
        else return ' not found';
    }
 
    public function offsetSet ($offset, $value)
    {
        echo 3,__METHOD__;   
    }
 
    public function offsetUnset ($offset)
    {
        echo 4,__METHOD__;
    }
}

$test = new Test();
echo $test['testUnit'].'<br>';
echo $test['getUnit'];

     类Test继承了ArrayAccess,并且重写了必须重写的4个方法,于是在使用数组式访问对象的时候就会自动去调用offsetGet($key)方法。于是我们能看到下面的输出结果,这种方式实际有点似曾相识的感觉,因为它和我们常见的__set和__get的很相似,只是__set和__get都是在属性找不到时再去进行的操作,而数组式访问是只要是使用数组访问就会调用offset这一系列的方法。上面的只是示例,更好的组织是在类中定义一个数组属性,然后所有的offset系列方法都操作这个数组里的值。

2Test::offsetGet -first
2Test::offsetGet testunit

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林戈的IT生涯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值