Laravel 阅读源码笔记

Laravel 阅读源码有感笔记

今天花了一天时间看了下Laravel 源码,Laravel 源码看的过程比较慢,东西比较多,文件跳转的多,看起来比较耗时间,在这里把今天看的收获分享下,可能存在漏洞或者是理解错误,这里不做100%准确性,只说自己的理解,如果理解不对,欢迎大家指出。

启动时

Application 构造函数

 public function __construct($basePath = null)
    {

        if ($basePath) {
            $this->setBasePath($basePath);
        }
        //将基本绑定注册到容器中
        $this->registerBaseBindings();
        //注册服务提供者
        $this->registerBaseServiceProviders();
        //注册核心容器别名
        $this->registerCoreContainerAliases();

    }
  • 绑定基础路径 默认是根目录下
$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

如果你想换个名字目录,可以修改成你想要的位置
之后会注册绑定基础路径

$this->instance('path', $this->path());
$this->instance('path.base', $this->basePath());
$this->instance('path.lang', $this->langPath());
$this->instance('path.config', $this->configPath());
$this->instance('path.public', $this->publicPath());
$this->instance('path.storage', $this->storagePath());
$this->instance('path.database', $this->databasePath());
$this->instance('path.resources', $this->resourcePath());
$this->instance('path.bootstrap', $this->bootstrapPath());

public function instance($abstract, $instance) 方法是绑定 $abstract 这个对应的实例化数据。

那么可以通过以下操作访问到这些绑定实例化过的数据
解析

$app->make('path.bootstrap');获得这些绑定值
  • 将基本绑定注册到容器中 protected function registerBaseBindings()
   protected function registerBaseBindings()
    {
        //容器注入到静态变量$instance
        static::setInstance($this);
        //绑定app为当前的实例化
        $this->instance('app', $this);
        //Container::class 绑定到当前实例
        $this->instance(Container::class, $this);
        //Mix::class 单例绑定里面
        $this->singleton(Mix::class);
        //PackageManifest::class 绑定匿名方法
        $this->singleton(PackageManifest::class, function () {
            return new PackageManifest(
                new Filesystem, $this->basePath(), $this->getCachedPackagesPath()
            );
        });
    }
  • 注册基础服务器 registerBaseServiceProviders
 protected function registerBaseServiceProviders()
    {
        //注册事件
        $this->register(new EventServiceProvider($this));
        $this->register(new LogServiceProvider($this));
        $this->register(new RoutingServiceProvider($this));
    }

这里将提供者的类注册下,会执行这些类的一个方法 $provider->register();,如果这个提供者还存在2个属性变量 bindings,singletons

如果是 bindings 则会去帮你自动化绑定 bind ,

如果是 singleton 则会去帮你自动化绑定 bind ,并且是全局,里面有个share

//默认绑定不是shared
 public function bind($abstract, $concrete = null, $shared = false){

 }

这个bind,最终会试下数组的绑定,格式参考如下

 $this->bindings[$abstract] = compact('concrete', 'shared');

其中concrete 样子可以参考如下

 protected function getClosure($abstract, $concrete)
    {
        return function ($container, $parameters = []) use ($abstract, $concrete) {

            if ($abstract == $concrete) {

                return $container->build($concrete);
            }

            return $container->resolve(
                $concrete, $parameters, $raiseEvents = false
            );
        };
    }
////绑定是shared
  public function singleton($abstract, $concrete = null)
    {

        $this->bind($abstract, $concrete, true);
    }
//$this->serviceProviders[]
//$this->loadedProviders[get_class($provider)]=true;
  • 注册核心容器别名 registerCoreContainerAliases()

会把默认的那些类绑定的对应关系,解析到2个数组变量里面

$this->aliases=[
    [Illuminate\Foundation\Application] => app
    [Illuminate\Contracts\Container\Container] => app
    [Illuminate\Contracts\Foundation\Application] => app
    [Psr\Container\ContainerInterface] => app
    [Illuminate\Auth\AuthManager] => auth
    [Illuminate\Contracts\Auth\Factory] => auth
    [Illuminate\Contracts\Auth\Guard] => auth.driver
    [Illuminate\View\Compilers\BladeCompiler] => blade.compiler
    [Illuminate\Cache\CacheManager] => cache
    [Illuminate\Contracts\Cache\Factory] => cache
    [Illuminate\Cache\Repository] => cache.store
    [Illuminate\Contracts\Cache\Repository] => cache.store
    [Psr\SimpleCache\CacheInterface] => cache.store
    [Symfony\Component\Cache\Adapter\Psr16Adapter] => cache.psr6
    [Symfony\Component\Cache\Adapter\AdapterInterface] => cache.psr6
    [Psr\Cache\CacheItemPoolInterface] => cache.psr6
    [Illuminate\Config\Repository] => config
    [Illuminate\Contracts\Config\Repository] => config
    [Illuminate\Cookie\CookieJar] => cookie
    [Illuminate\Contracts\Cookie\Factory] => cookie
    [Illuminate\Contracts\Cookie\QueueingFactory] => cookie
    [Illuminate\Encryption\Encrypter] => encrypter
    [Illuminate\Contracts\Encryption\Encrypter] => encrypter
    [Illuminate\Database\DatabaseManager] => db
    [Illuminate\Database\ConnectionResolverInterface] => db
    [Illuminate\Database\Connection] => db.connection
    [Illuminate\Database\ConnectionInterface] => db.connection
    [Illuminate\Events\Dispatcher] => events
    [Illuminate\Contracts\Events\Dispatcher] => events
    [Illuminate\Filesystem\Filesystem] => files
    [Illuminate\Filesystem\FilesystemManager] => filesystem
    [Illuminate\Contracts\Filesystem\Factory] => filesystem
    [Illuminate\Contracts\Filesystem\Filesystem] => filesystem.disk
    [Illuminate\Contracts\Filesystem\Cloud] => filesystem.cloud
    [Illuminate\Hashing\HashManager] => hash
    [Illuminate\Contracts\Hashing\Hasher] => hash.driver
    [Illuminate\Translation\Translator] => translator
    [Illuminate\Contracts\Translation\Translator] => translator
    [Illuminate\Log\LogManager] => log
    [Psr\Log\LoggerInterface] => log
    [Illuminate\Mail\MailManager] => mail.manager
    [Illuminate\Contracts\Mail\Factory] => mail.manager
    [Illuminate\Mail\Mailer] => mailer
    [Illuminate\Contracts\Mail\Mailer] => mailer
    [Illuminate\Contracts\Mail\MailQueue] => mailer
    [Illuminate\Auth\Passwords\PasswordBrokerManager] => auth.password
    [Illuminate\Contracts\Auth\PasswordBrokerFactory] => auth.password
    [Illuminate\Auth\Passwords\PasswordBroker] => auth.password.broker
    [Illuminate\Contracts\Auth\PasswordBroker] => auth.password.broker
    [Illuminate\Queue\QueueManager] => queue
    [Illuminate\Contracts\Queue\Factory] => queue
    [Illuminate\Contracts\Queue\Monitor] => queue
    [Illuminate\Contracts\Queue\Queue] => queue.connection
    [Illuminate\Queue\Failed\FailedJobProviderInterface] => queue.failer
    [Illuminate\Routing\Redirector] => redirect
    [Illuminate\Redis\RedisManager] => redis
    [Illuminate\Contracts\Redis\Factory] => redis
    [Illuminate\Redis\Connections\Connection] => redis.connection
    [Illuminate\Contracts\Redis\Connection] => redis.connection
    [Illuminate\Http\Request] => request
    [Symfony\Component\HttpFoundation\Request] => request
    [Illuminate\Routing\Router] => router
    [Illuminate\Contracts\Routing\Registrar] => router
    [Illuminate\Contracts\Routing\BindingRegistrar] => router
    [Illuminate\Session\SessionManager] => session
    [Illuminate\Session\Store] => session.store
    [Illuminate\Contracts\Session\Session] => session.store
    [Illuminate\Routing\UrlGenerator] => url
    [Illuminate\Contracts\Routing\UrlGenerator] => url
    [Illuminate\Validation\Factory] => validator
    [Illuminate\Contracts\Validation\Factory] => validator
    [Illuminate\View\Factory] => view
    [Illuminate\Contracts\View\Factory] => view
]
$this->abstractAliases=[

 [app] => Array
        (
            [0] => Illuminate\Foundation\Application
            [1] => Illuminate\Contracts\Container\Container
            [2] => Illuminate\Contracts\Foundation\Application
            [3] => Psr\Container\ContainerInterface
        )

    [auth] => Array
        (
            [0] => Illuminate\Auth\AuthManager
            [1] => Illuminate\Contracts\Auth\Factory
        )

    [auth.driver] => Array
        (
            [0] => Illuminate\Contracts\Auth\Guard
        )

    [blade.compiler] => Array
        (
            [0] => Illuminate\View\Compilers\BladeCompiler
        )

    [cache] => Array
        (
            [0] => Illuminate\Cache\CacheManager
            [1] => Illuminate\Contracts\Cache\Factory
        )

    [cache.store] => Array
        (
            [0] => Illuminate\Cache\Repository
            [1] => Illuminate\Contracts\Cache\Repository
            [2] => Psr\SimpleCache\CacheInterface
        )

    [cache.psr6] => Array
        (
            [0] => Symfony\Component\Cache\Adapter\Psr16Adapter
            [1] => Symfony\Component\Cache\Adapter\AdapterInterface
            [2] => Psr\Cache\CacheItemPoolInterface
        )

    [config] => Array
        (
            [0] => Illuminate\Config\Repository
            [1] => Illuminate\Contracts\Config\Repository
        )

    [cookie] => Array
        (
            [0] => Illuminate\Cookie\CookieJar
            [1] => Illuminate\Contracts\Cookie\Factory
            [2] => Illuminate\Contracts\Cookie\QueueingFactory
        )

    [encrypter] => Array
        (
            [0] => Illuminate\Encryption\Encrypter
            [1] => Illuminate\Contracts\Encryption\Encrypter
        )

    [db] => Array
        (
            [0] => Illuminate\Database\DatabaseManager
            [1] => Illuminate\Database\ConnectionResolverInterface
        )

    [db.connection] => Array
        (
            [0] => Illuminate\Database\Connection
            [1] => Illuminate\Database\ConnectionInterface
        )

    [events] => Array
        (
            [0] => Illuminate\Events\Dispatcher
            [1] => Illuminate\Contracts\Events\Dispatcher
        )

    [files] => Array
        (
            [0] => Illuminate\Filesystem\Filesystem
        )

    [filesystem] => Array
        (
            [0] => Illuminate\Filesystem\FilesystemManager
            [1] => Illuminate\Contracts\Filesystem\Factory
        )

    [filesystem.disk] => Array
        (
            [0] => Illuminate\Contracts\Filesystem\Filesystem
        )

    [filesystem.cloud] => Array
        (
            [0] => Illuminate\Contracts\Filesystem\Cloud
        )

    [hash] => Array
        (
            [0] => Illuminate\Hashing\HashManager
        )

    [hash.driver] => Array
        (
            [0] => Illuminate\Contracts\Hashing\Hasher
        )

    [translator] => Array
        (
            [0] => Illuminate\Translation\Translator
            [1] => Illuminate\Contracts\Translation\Translator
        )

    [log] => Array
        (
            [0] => Illuminate\Log\LogManager
            [1] => Psr\Log\LoggerInterface
        )

    [mail.manager] => Array
        (
            [0] => Illuminate\Mail\MailManager
            [1] => Illuminate\Contracts\Mail\Factory
        )

    [mailer] => Array
        (
            [0] => Illuminate\Mail\Mailer
            [1] => Illuminate\Contracts\Mail\Mailer
            [2] => Illuminate\Contracts\Mail\MailQueue
        )

    [auth.password] => Array
        (
            [0] => Illuminate\Auth\Passwords\PasswordBrokerManager
            [1] => Illuminate\Contracts\Auth\PasswordBrokerFactory
        )

    [auth.password.broker] => Array
        (
            [0] => Illuminate\Auth\Passwords\PasswordBroker
            [1] => Illuminate\Contracts\Auth\PasswordBroker
        )

    [queue] => Array
        (
            [0] => Illuminate\Queue\QueueManager
            [1] => Illuminate\Contracts\Queue\Factory
            [2] => Illuminate\Contracts\Queue\Monitor
        )

    [queue.connection] => Array
        (
            [0] => Illuminate\Contracts\Queue\Queue
        )

    [queue.failer] => Array
        (
            [0] => Illuminate\Queue\Failed\FailedJobProviderInterface
        )

    [redirect] => Array
        (
            [0] => Illuminate\Routing\Redirector
        )

    [redis] => Array
        (
            [0] => Illuminate\Redis\RedisManager
            [1] => Illuminate\Contracts\Redis\Factory
        )

    [redis.connection] => Array
        (
            [0] => Illuminate\Redis\Connections\Connection
            [1] => Illuminate\Contracts\Redis\Connection
        )

    [request] => Array
        (
            [0] => Illuminate\Http\Request
            [1] => Symfony\Component\HttpFoundation\Request
        )

    [router] => Array
        (
            [0] => Illuminate\Routing\Router
            [1] => Illuminate\Contracts\Routing\Registrar
            [2] => Illuminate\Contracts\Routing\BindingRegistrar
        )

    [session] => Array
        (
            [0] => Illuminate\Session\SessionManager
        )

    [session.store] => Array
        (
            [0] => Illuminate\Session\Store
            [1] => Illuminate\Contracts\Session\Session
        )

    [url] => Array
        (
            [0] => Illuminate\Routing\UrlGenerator
            [1] => Illuminate\Contracts\Routing\UrlGenerator
        )

    [validator] => Array
        (
            [0] => Illuminate\Validation\Factory
            [1] => Illuminate\Contracts\Validation\Factory
        )

    [view] => Array
        (
            [0] => Illuminate\View\Factory
            [1] => Illuminate\Contracts\View\Factory
        )
];

这个构造的方法初始就是这样子,然后我们现在来总结下几个里面调用的方法

  • instance($abstract, $instance) 将现有对象实例绑定到容器中,并存入变量数组名$this->instances[$abstract]里面,

  • singleton($abstract, $concrete = null) 绑定单例数据到 ,实际上是也是调用bind方法,只是shared标识为真,第二个参数是最终要执行的类或是匿名方法

  • bind($abstract, $concrete = null, $shared = false) 方法的第一个参数为要绑定的类 / 接口名,第二个参数是一个返回类实例的 Closure,通常用于绑定接口数据驱动

  • resolve($abstract, $parameters = [], $raiseEvents = true) 通过PHP的反射类实例化对象 ,第一个参数为要绑定的,第二个参数,第三个 包含别名的事件

  • make($abstract, array $parameters = []) ,其实就是调用了resolve

几个单例的绑定

$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class  //最终执行的类
);

$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class  //最终执行的类
);

$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class  //最终执行的类
);

实例化内核

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);//这类绑定了 App\Http\Kernel::class,所以回去执行这个类的方法
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

这里把http请求传递给handle方法

vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php  

  //通过中间件/路由器发送给定的请求。
  protected function sendRequestThroughRouter($request)
    {
        //绑定实例化
        $this->app->instance('request', $request);

        Facade::clearResolvedInstance('request');

        $this->bootstrap();

        return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());
    }

经过查阅,会去执行如下的驱动

protected $bootstrappers = [
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class, //环境.env
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class, //配置文件
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class, //异常处理
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class, //注册RegisterFacades
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class, //实例化 providers 里面的服务提供者 
        \Illuminate\Foundation\Bootstrap\BootProviders::class,//执行 providers里面的 boot()方法
    ];

send() 设置通过管道发送的对象

*此扩展管道捕获每个切片期间发生的任何异常。
*异常被转换为HTTP响应,以便进行适当的中间件处理。
return (new Pipeline($this->app))
                    ->send($request)
                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                    ->then($this->dispatchToRouter());

最后注册 terminate命令行

$kernel->terminate($request, $response);

总结

看完之后,总算有个大概的知道一个过程和实践的代码位置。因为里面的方法太多,无法一一讲解,需要大家去用到的时候找找。
黑白课堂

提示

评论区 (0)

没有记录
支持 markdown,图片截图粘贴拖拽都可以自动上传。
黑白课堂

黑白课堂

混元大罗金仙 站长创业者玉树凌风每天醒来0收入

查看更多

最新视频课程

Laravel 的 PhpSpreadsheet 包入门

wap2App 入门讲解,100%速成,全面为你讲解。

ace.js 打造一款属于你的 Web 编辑器,入门文档。

Laravel Permission 中文文档

解释 OAuth 2.0 认证 和使用场景说明

Laravel 实现 RBAC 权限管理功能 Permission 包操作

钻级赞助商