[转发]laravel实现日志接口Contracts
应用
控制器只需要一个带有 log()
方法的 Logger 类,所以我们的接口也必须定义一个 log()
方法。
interface LogInterface
{
public function log($content);
}
接口只包含方法声明而不包含它的实现,这就是它被称为 抽象
的原因。
在我们实现接口时,实现接口的类必须提供接口中定义的 抽象方法
的实现细节。
再回到我们的代码,我们改写成以下:
// LogController
class LogController extends Controller
{
public function log(LogInterface $logger)
{
$logger->log('log to');
}
}
//DBLogger.php
namespace App\Logs;
use App\Contracts\LogInterface;
class DBLogger implements LogInterface
{
public function log($content)
{
//输出日志到 DB。
}
}
//FileLogger.php
namespace App\Logs;
use App\Contracts\LogInterface;
class FileLogger implements LogInterface
{
public function log($content)
{
//输出 Log 日志到文件。
}
}
//CouldLogger.php
namespace App\Logs;
use App\Contracts\LogInterface;
class CouldLogger implements LogInterface
{
public function log($content)
{
//输出 Log 日志到云。
}
}
现在我们的代码灵活且松耦合,无需触及现有代码,就可以随时改变 Logger 的实现来应对需求的变化:
class RedisLogger implements Logger
{
public function log($content)
{
//输出 Log 日志到redis。
}
}
依赖注入
在使用 Laravel 框架时,我们可以利用它的服务容器来自动注入接口的实现。
我们先新建一个配置文件 config/log.php
<?php
return [
'default' => env('LOG_TARGET', 'file'),
'file' => [
'class' => App\Logs\FileLogger::class,
],
'db' => [
'class' => App\Logs\DBLogger::class,
],
'redis' => [
'class' => App\Logs\RedisLogger::class,
]
];
绑定接口至实现
并在 app/Providers/AppServiceProvider.php 添加以下代码。
public function register()
{
$default = config('log.default');
$logger = config("log.{$default}.class");
$this->app->bind(
\App\Contracts\LogInterface::class,
$logger
);
}
我们从配置文件中读取默认 Logger,并将其绑定到 LogInterface。这样每当我们请求 Logger 接口时,容器都会解析它并返回默认的 Logger 实例。
默认 Logger 是在 env() 配置的,我们可以在不同的环境中使用不同的 Logger,例如本地环境中记录到文件、生产环境中记录到数据库。
————————————————
原文作者:MArtian
转自链接:博客:聊聊 Interface 在 Laravel 开发中的使用
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。
本作品采用《CC 协议》,转载必须注明作者和本文链接
我说看着这么眼熟呢,MArtian 写的啊~