laravel工作流程以及自定义provider创建

laravel 的整个框架中,任何一个模块都可以删除和修改,也可以任意增加自己的模块,这也是laravel的灵活和强大之处。

laravel工作流程以及自定义provider创建

首先 laravel构架的文件都在下面这个文件夹中

vendor/laravel/framework/src
具体流程

1.首先进入我们熟悉的public下面,这是项目访问的默认目录,打开index.php,加载了一个app文件

$app = require_once __DIR__.'/../bootstrap/app.php';

2.打开这个bootstrap/app.php,看到里面实例化了一个叫做Application的类

$app = new Illuminate\Foundation\Application(    realpath(__DIR__.'/../'));

3.打开这个文件,发现这个application文件继承了container对象

class Application extends Container

4.所以这个bootstrap下面的app.php其实是实例化了Application,而Application又继承自容器对象。

5.重新回到bootstrap/app.php,发现他在里面绑定了很多类并返回,
每个绑定里面有两个类,第一个是接口,第二个才是真正的类。

  $app->singleton(Illuminate\Contracts\Http\Kernel::class,    App\Http\Kernel::class);
    ......
    return $app;

6.所以我们自己也可以在这里绑定我们自己写的类,并通过下面两种方法来调用。

//绑定自己的类
$app->singleton('Test',App\Http\Test);
//调用(全局环境下)
$u = $this->app->make('Test');
$u = $this->appp['Test'];

这个就叫做工厂模式,所谓工厂的意思就是,以前你要每次实例化一个类才能获得这个类的方法属性,但是现在你可以通过make(),或app[''],得到这个类。

7.假如你写了以下两个对象,将Ta对象作为参数传入Tb对象的构造函数中,将会自动为你实例化Ta类为ta,这个叫做依赖注入,经常看到的(REQUEST $request),就是这个道理。但是前提是你的Ta 和Tb类都已经绑定注册过了。

class Ta
{
  public $jacklin;
   public function test()    
  {       
 echo 'tb';   
  }
}
 class Tb
{
    private $ta;

    public function __construct(Ta $ta)
    {
        $this->ta = $ta;
    }

    public function test()
    {
       echo "tb";
    }
}

8.刚才说到,我们自定义的对象可以在bootstrap/app.php中绑定注册,但是这个文件是个入口文件,多人合作的项目中,合并版本的时候会遇到冲突,所以要有一个合适的位置进行注册绑定的步骤。全局唯一的文件肯定不合适,那么控制器能不能注册呢,不行,比如(Request $request)这个例子来说,肯定是要先已经注册过Request这个类,才能依赖注入,所以假如写在控制器有很多情况是无法使用我们注册的类的。那么重新回到开始的文件,在public/index.php下,除了刚才的加载app类,还有下面一句

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

这句话按照他的文件去找我是蒙逼了,但是大概的意思就是make了一个http的kernel内核,按照龙哥的指示,直接找到http下面的kernel

9.找到app/Http/Kernel之后发现他除了加载我们熟悉的中间件,还继承了一个内核文件

use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel{}

找到这个文件,发现下面的启动数组,环境,配置,处理异常等等。laravel会遍历这个数组,把里面的东西分别启动。

protected $bootstrappers = [
    'Illuminate\Foundation\Bootstrap\DetectEnvironment',
    'Illuminate\Foundation\Bootstrap\LoadConfiguration',//config/app.php
    'Illuminate\Foundation\Bootstrap\ConfigureLogging',
    'Illuminate\Foundation\Bootstrap\HandleExceptions',
    'Illuminate\Foundation\Bootstrap\RegisterFacades',
    'Illuminate\Foundation\Bootstrap\RegisterProviders',//注册服务提供者
    'Illuminate\Foundation\Bootstrap\BootProviders',
];

在加载配置的时候,程序会加载config里面中的app.php,有一段下面的程序,可以看到,他加载了所有的服务提供者的模块。并且 'Illuminate\Foundation\Bootstrap\RegisterProviders',会把app.php里面记录的的服务提供者都注册

  'providers' => [

    /*
     * Laravel Framework Service Providers...
     */
    Illuminate\Foundation\Providers\ArtisanServiceProvider::class,
    Illuminate\Auth\AuthServiceProvider::class,
    Illuminate\Broadcasting\BroadcastServiceProvider::class,
    Illuminate\Bus\BusServiceProvider::class,
    Illuminate\Cache\CacheServiceProvider::class,
    Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
    Illuminate\Routing\ControllerServiceProvider::class,
    Illuminate\Cookie\CookieServiceProvider::class,
    Illuminate\Database\DatabaseServiceProvider::class,
    Illuminate\Encryption\EncryptionServiceProvider::class,
    Illuminate\Filesystem\FilesystemServiceProvider::class,
    Illuminate\Foundation\Providers\FoundationServiceProvider::class,
    Illuminate\Hashing\HashServiceProvider::class,
    Illuminate\Mail\MailServiceProvider::class,
    Illuminate\Pagination\PaginationServiceProvider::class,
    Illuminate\Pipeline\PipelineServiceProvider::class,
    Illuminate\Queue\QueueServiceProvider::class,
    Illuminate\Redis\RedisServiceProvider::class,
    Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
    Illuminate\Session\SessionServiceProvider::class,
    Illuminate\Translation\TranslationServiceProvider::class,
    Illuminate\Validation\ValidationServiceProvider::class,
    Illuminate\View\ViewServiceProvider::class,

    /*
     * Application Service Providers...
     */
    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
], 

9.那么我们要注册的方法到底在哪里呢,找到App/Providers,随便打开里面的文件。发现下面代码

use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider

打开这个文件

public function __construct($app){$this->app = $app;}

发现这个类注入了app对象,所以在Provider的范围内也可以写

$this->app

重新回到刚才打开的AppServiceProvider,里面有一个注册方法

public function register()

这里就是我们要注册自己写的类的地方了,把我们绑定的语句写进来,注意是$this->app

public function register()
{
    $this->app->singleton(\App\Ta::class,\App\Ta::class);
    $this->app->singleton(\App\Tb::class,\App\Tb::class);
}

这里要注意命名空间的问题,App前面要加上\从根命名空间查找

这样,laravel加载内核文件的时候,就会将我们写好的服务提供者文件加载进去。

刚才是在AppServiceProvider中注册了我们的模块,那怎么创建自己的Provider呢,首先在同样的目录下创建文件JacklinServiceProvider.php,基础内容可以从别的Provider文件复制,然后同样在注册方法中写入自己的类,最后,还要在刚才的config\app.php中的,providers[]里面加入我们新的服务提供者类,OK了。

10.上面已经能够把我们自己写的模块加进去了,那还有一个问题,我们这样每次调用自己的模块都要通过工厂模式make出来,还是很麻烦,但是系统的方法似乎很简单,比如DB::,Input::,就 可以直接调用方法,这是为什么呢?laravel又提供了另外一个东西,叫做facades,这个单词的本意是门面的意思,下面开始解释这个东西。

首先随意创建一个Test.php,我们先创建在App\Http,写入以下内容

    <?php

namespace App\Http\Facades;

class Ta extends \Illuminate\Support\Facades\Facade
{
    protected static function getFacadeAccessor()
    {
        return '\App\Ta';
    }
}

从内容上不难看到,这是\Illuminate\Support\Facades\Facade,的一个方法,大概的意思就是把Ta这个对象实例化出来,并且嵌套在自己的一个静态方法里面,给这个class起个跟Ta一样的名字,那么当你Ta的时候,这个类也就加载了\App\Ta,所以就造成了Ta::也能用Ta里面的方法。

//调用
App\Http\Facades\Ta::test();

这么调用好像也很麻烦,怎么样能像DB::那样直接用呢,还有一步,配置aliases,本意别名

还是刚才的config/app.php中,在aliases中加入

'Jacklin'   => App\Http\Facades\Ta::class,

这样又把Ta类的方法转移到了Jacklin身上,试试,下面方法可以执行,一套自己的‘静态’provider就弄好了,而且还把访问的方式美化了,这也就是laravel用facader这个词命名这个方法的意思吧

Jacklin::test();    

11.最后刚才创建的这个JacklinServiceProvider.php是随便放了个文件夹,显然不合适,那么在app/Http 下面创建一个Facades文件夹,然后把JacklinServiceProvider.php放进去,并修改命名空间即可。

12.另外,我们的Ta Tb也是直接创建在了app里,同样的道理,在app/Http下建立Module文件夹,把我们的模块放进去。

总结

为了便于记忆,整理一下完成一个provider的思路。
1.建立Modules文件夹和Facades
2.在Modules建立模块文件Test.php
3.在Provider中建立TestServiceProvider.php,复制AppServiceProvider.php,里的基础内容,在register()方法中注册前面写的Test模块

  $this->app->singleton(\App\Http\Modules\Test::class,\App\Http\Modules\Test::class);

4.在config/app.php的providers[]中加入

App\Providers\TestServiceProvider::class,

5.在app/Http/Facades中建立Jacklin.php,模仿静态方法

<?php

namespace App\Http\Facades;

class Test extends \Illuminate\Support\Facades\Facade
{
    protected static function getFacadeAccessor()
    {
        return '\App\Http\Modules\Test';
    }
}

6.在config/app.php的aliases[]中加入

'Test' => App\Http\Facades\Test::class,

7.OK了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容