Laravel 源码解读:php artisan make:auth
学 Laravel 和 Vuejs,你真应该来 codecasts.com ,有免费高质量视频!
在 Laravel 5.2 的时候,官方给我们提供了 make:auth
命令,这个命令使得我们在执行一条命令的情况下实现用户注册和登录,忘记密码,找回密码的过程!本文来看一下 make:auth
的源码。
源码在哪
还是一样的,使用编辑器的搜索功能,直接搜索 MakeAuthCommand
,你会找到这个文件 Illuminate\Auth\Console\MakeAuthCommand
,而这些 artisan 的命令,我们关注的重点就是 fire()
这个方法:
public function fire() { $this->createDirectories(); // other codes ... }
1.创建目录
首先 createDirectories()
创建必要的目录:
protected function createDirectories() { if (! is_dir(resource_path('views/layouts'))) { mkdir(resource_path('views/layouts'), 0755, true); } if (! is_dir(resource_path('views/auth/passwords'))) { mkdir(resource_path('views/auth/passwords'), 0755, true); } }
这里可以看到此命令会创建两个文件夹,就是 resources/views/layouts
和 resources/views/auth/password
2.复制文件
有了目录之后,在 fire() 方法里,createDirectories()
的后面,大概有这样的一行代码:
public function fire() { // other codes ... $this->exportViews(); // other codes ... }
那么 exportViews() 做的事情就是复制文件了:
protected function exportViews() { foreach ($this->views as $key => $value) { if (file_exists(resource_path('views/'.$value)) && ! $this->option('force')) { if (! $this->confirm("The [{$value}] view already exists. Do you want to replace it?")) { continue; } } copy( __DIR__.'/stubs/make/views/'.$key, resource_path('views/'.$value) ); } }
首先通过 foreach 检查要复制的文件是否存在,不存在的话,直接使用 copy() 复制文件,这些文件名字的定义在 $this->views
里面:
protected $views = [ 'auth/login.stub' => 'auth/login.blade.php', 'auth/register.stub' => 'auth/register.blade.php', 'auth/passwords/email.stub' => 'auth/passwords/email.blade.php', 'auth/passwords/reset.stub' => 'auth/passwords/reset.blade.php', 'layouts/app.stub' => 'layouts/app.blade.php', 'home.stub' => 'home.blade.php', ];
这个定义就在 MakeAuthCommand
文件里面。然后这里你就可以清楚地看到我们要复制的视图文件有哪些了!
3.生成控制器
还是在 fire() 方法中,通过下面几行代码生成控制器:
file_put_contents( app_path('Http/Controllers/HomeController.php'), $this->compileControllerStub() );
我们来看看 compileControllerStub()
具体怎么实现:
protected function compileControllerStub() { return str_replace( '{{namespace}}', $this->getAppNamespace(), file_get_contents(__DIR__.'/stubs/make/controllers/HomeController.stub') ); }
可以看到,思路是这样的:1.获取原先定义好的控制器文件 --> 2.用 getAppNamespace
替换 {{namespace}}
;这样我们就可以正确确定控制器的命名空间。
4.添加路由
在 fire() 方法中,通过下面几行代码添加路由:
file_put_contents( base_path('routes/web.php'), file_get_contents(__DIR__.'/stubs/make/routes.stub'), FILE_APPEND );
注意 FILE_APPEND
这个参数,就是将 routes.stub
这个文件的内容附加在原来路由文件的后面,并不会将原来的路由清零。那么添加的是下面的这两条路由:
Auth::routes(); Route::get('/home', 'HomeController@index')->name('home');
其中的 Auth::routes() 方法可以直接在 Illuminate\Support\Facades\Auth
:
public static function routes() { static::$app->make('router')->auth(); }
最终执行路由注册的在 Illuminate\Routing\Router
的 auth()
方法:
public function auth(){ // routes codes ... }
最后揭秘
那么这些视图文件
,控制器文件
和路由文件
在哪呢?揭秘:就在 vendor/laravel/framework/src/Illuminate/Auth/Console/stubs/make
目录,你打开这个目录就可以看到这些魔法的真相!
Happy Hacking
最后记得关注 codecasts 公众号,定期送书送福利!