Laravel 源码解读:PHP artisan down
Laravel 的 php artisan down 命令通常是在我们维护的时候使用的,因为在执行这条命令的时候,我们的 laravel 应用就进入了维护
模式,会出现一个类似于下面这个 Be Ringht Back
页面
源码在哪
还是一样,我们首先找到 artisan down 命令的源码所在,它位于 Illuminate\Foundation\Console\DownCommand
中
Tips:依然是可以直接使用编辑器搜索
DownCommand
。
解读
主体方法还是 fire()
:
public function fire()
{
file_put_contents(
$this->laravel->storagePath().'/framework/down',
json_encode($this->getDownFilePayload(), JSON_PRETTY_PRINT)
);
$this->comment('Application is now in maintenance mode.');
}
这里的代码其实非常简单,就是使用 file_put_contents()
将 json_encode($this->getDownFilePayload()
内容写入storage/framework/down
文件中,这个文件很重要!。storagePath()
就是位于 Illuminate\Foundation\Application
中的:
public function storagePath()
{
return $this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage';
}
也就是项目目录的 storage/
文件路径。
写入的内容是什么?
文件内容是由 $this->getDownFilePayload()
生成,其实很简单的,就是在 DownCommand
中:
protected function getDownFilePayload()
{
return [
'time' => Carbon::now()->getTimestamp(),
'message' => $this->option('message'),
'retry' => $this->getRetryTime(),
];
}
这里只返回一个数组,记录三个关键的信息:time
, message
, retry
;这样看来其实我们可以自定义 Be Right Back 的字样的吧,也可以定义提示的时间,我们可以这样验证:
然后这样使用:
怎么判断是否是维护模式
超级简单,就在 Laravel 的核心类 Illuminate\Foundation\Application
中,启动之前先检查是否是维护模式 isDownForMaintenance()
:
public function isDownForMaintenance()
{
return file_exists($this->storagePath().'/framework/down');
}
你看,简单吧!它就是直接检测 storage/framework/down
是否存在!Neat!
最后
总结就是,执行 php artisan down 命令的时候,主要是生成 storage/framework/down
文件,包含了 time message 和 retry 三个关键信息,然后在 Laravel 启动的时候检测 storage/framework/down
文件是否存在就可以了。如果存在该文件,那就认为项目处于维护状态。
广告时间
坚持每天更新的公众号 codecasts,最近也在送书!有兴趣的可以关注一下
本作品采用《CC 协议》,转载必须注明作者和本文链接
0回复惨案?
消灭0回复
这个功能相对api应用来说比较鸡肋
@jacobsun 炉门 已经砍了!
嘿嘿
@jacobsun 这个不应该是 api 的应用场景
@JellyBool 会有需求因为某些原因临时维护服务器呀,
php artisan down
其实也是这个需求 不过只考虑到了MVC
的场景 没有考虑到API
的场景... 那这时候只能自己实现 还要php artisan down
不就是鸡肋了嘛楼方这个字体是啥 ide的字段看起来 蛮苗条的
我的 laravel 项目是api场景,我在中间件
CheckForMaintenanceMode
里找到一个MaintenanceModeException
异常类,所以想到了在App\Exceptions\Handler
中这样写这样前端拿到code 为1000时就知道api暂时不能用了,刚接触laravel,也不知道这样写合不合适,目前实现效果倒是可以了
@renqun Laravel8 在默认情况下,执行
php artisan down
以后,不论访问 WEB 还是 API 都不再抛出MaintenanceModeException
异常,而是HttpException
异常。这时我们访问 API 就会报错:这样的结果对于客户端显然是不能忍的
。那么如何能给客户端返回正确的
JSON
格式数据呢?解决办法是:在
App\Http\Middleware\PreventRequestsDuringMaintenance
中间件里做手脚,因为这个文件在App\Http\Kernel
中已经被引入到了全局的中间件数组中。“全局的中间件”意思就是不论访问 WEB 还是 API 都会把这个数组中的中间件走一遍。我们可以在
handle()
方法中,检测 uri 是否为 api 开头。是的话就返回一个正常的 json 响应,不是的话,就由父类继续执行:这样,所有的 API 请求都会返回正常的 json 格式数据了: