日志框架php,日志 · 手摸手带你创建php现代化框架 · 看云

## psr-3规范

```

composer require psr/log

```

(`psr` 见 关于`psr规范解释`)

这篇的跟`数据库连接 (多例模式)` 有些类似,同样是 `多例模式`

## 创建配置文件 config/log.php

```

return [

'default' => 'file1',

'channels' => [

'file1' => [ // 文件类型的日志

'driver' => 'stack',

'path' => FRAME_BASE_PATH.'/storage/',

'format' => '[%s][%s] %s', // 格式化类型 分别代表:[日期][日志级别]消息

],

'file2' => [

'driver' => 'daily',

'path' => FRAME_BASE_PATH.'/storage/',

'format' => '[%s][%s] %s', // 格式化类型

]

]

];

```

## 创建core/log/driver/StackLogger.php

这个日志是把所有内容都放同一个文件的。

现在可以直接 `new` 这个类,传递配置进去就可以了。

但是这样不完善,如果想用 按日期分类的日志怎么办?

所以想要一个 `调用者` 来控制,这个 `调用者是多例的`。

```

namespace core\log\driver;

use Illuminate\Contracts\Validation\ValidatesWhenResolved;

use Psr\Log\AbstractLogger;

use Psr\Log\LoggerInterface;

use Psr\Log\LoggerTrait;

class StackLogger extends AbstractLogger

{

protected $config;

public function __construct(array $config)

{

$this->config = $config;

}

// 来自: https://learnku.com/docs/psr/psr-3-logger-interface/1607

/**

* @example 代码:app('log')->info('{language} is the best language in the world’,['language' => 'php']) 返回: php is the best language in the world

* @example 说白了 就是替换而已

* @param $message 原本消息

* @param $context 上下文 要替换的

* @return string

*/

public function interpolate($message, array $context = array())

{

// 构建一个花括号包含的键名的替换数组

$replace = array();

foreach ($context as $key => $val) {

// 检查该值是否可以转换为字符串

if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {

$replace['{' . $key . '}'] = $val;

}

}

// 替换记录信息中的占位符,最后返回修改后的记录信息。

return strtr($message, $replace);

}

/**

* @inheritDoc

*/

public function log($level, $message, array $context = array())

{

if( is_array($message))

$message = var_export($message,true) . var_export($context,true); // 设置true 不输出

else if( is_string($message)) // 内容是字符串 并且 $context是数组 替换占位符

$message = $this->interpolate($message,$context);

$message = sprintf($this->config['format'],date('y-m-d h:m:s'),$level,$message); // 根据配置文件格式化

/**

* error_log函数解释

* @param $message 日志内容

* @param $message_type 类型 3是写入到文件

* @param $destination 因为是3 填文件路径

*/

error_log($message.PHP_EOL,3,$this->config['path'].'/php_frame.log');

}

}

```

### 关于AbstractLogger.php的解释

这个是 `psr-log` 自带的类,很简单,只有几个方法。

可以让我们少些几行代码。

![](https://img.kancloud.cn/7d/dd/7dddc233966a2d3360753e287b29bee7_774x1005.png)

## 创建调用者 core/log/Logger.php

```

namespace core\log;

use core\log\driver\DailyLogger;

use core\log\driver\StackLogger;

class Logger

{

protected $channels = []; // 所有的实例化的通道 就是多例而已

protected $config;

public function __construct()

{

$this->config = \App::getContainer()->get('config')->get('log');

}

public function channel($name = null)

{

if(! $name) // 没选择名字

$name = $this->config['default'];

if( isset($this->channels[$name]))

return $this->channels[$name];

$config = \App::getContainer()->get('config')->get('log.channels.'.$name);

//如:$config['driver'] = stack, 则调用createStack($config);

return $this->channels['name'] = $this->{'create'.ucfirst($config['driver'])}($config);

}

// 放在同一个文件

public function createStack($config)

{

return new StackLogger($config);

}

public function __call($method, $parameters)

{

return $this->channel()->$method(...$parameters);

}

}

```

## 绑定到容器

![](https://img.kancloud.cn/b2/af/b2af6a95b71e9163b2102e67ca2c248d_790x308.png)

## 运行

![](https://img.kancloud.cn/1a/8c/1a8cdaf45d326b2990df2c100a3a6127_948x199.png)

![](https://img.kancloud.cn/6b/1f/6b1fdeedf243210ca2ec17031ddd6d54_964x186.png)

![](https://img.kancloud.cn/d5/23/d5237af3d354463915b6869e028f59b9_1094x422.png)

## 结尾

![](https://img.kancloud.cn/da/5e/da5e4ee1e2caf60cfb95fb0e297e9702_844x491.png)

`driver` = `daily` 本教程未实现,太多代码了。

但是读者可自行实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值