tp5框架使用composer实现日志记录功能示例


Posted in PHP onJanuary 10, 2019

本文实例讲述了tp5框架使用composer实现日志记录功能。分享给大家供大家参考,具体如下:

tp5实现日志记录

1.安装 psr/log

composer require psr/log

tp5框架使用composer实现日志记录功能示例

它的作用就是提供一套接口,实现正常的日志功能!

我们可以来细细的分析一下,LoggerInterface.php

<?php
namespace Psr\Log;
/**
 * Describes a logger instance.
 *
 * The message MUST be a string or object implementing __toString().
 *
 * The message MAY contain placeholders in the form: {foo} where foo
 * will be replaced by the context data in key "foo".
 *
 * The context array can contain arbitrary data. The only assumption that
 * can be made by implementors is that if an Exception instance is given
 * to produce a stack trace, it MUST be in a key named "exception".
 *
 * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
 * for the full interface specification.
 */
interface LoggerInterface
{
  /**
   * System is unusable.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function emergency($message, array $context = array());
  /**
   * Action must be taken immediately.
   *
   * Example: Entire website down, database unavailable, etc. This should
   * trigger the SMS alerts and wake you up.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function alert($message, array $context = array());
  /**
   * Critical conditions.
   *
   * Example: Application component unavailable, unexpected exception.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function critical($message, array $context = array());
  /**
   * Runtime errors that do not require immediate action but should typically
   * be logged and monitored.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function error($message, array $context = array());
  /**
   * Exceptional occurrences that are not errors.
   *
   * Example: Use of deprecated APIs, poor use of an API, undesirable things
   * that are not necessarily wrong.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function warning($message, array $context = array());
  /**
   * Normal but significant events.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function notice($message, array $context = array());
  /**
   * Interesting events.
   *
   * Example: User logs in, SQL logs.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function info($message, array $context = array());
  /**
   * Detailed debug information.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function debug($message, array $context = array());
  /**
   * Logs with an arbitrary level.
   *
   * @param mixed $level
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function log($level, $message, array $context = array());
}

这是一套日志正常的接口,有层级,有消息,有具体的内容。

LogLevel.php

<?php
namespace Psr\Log;
/**
 * Describes log levels.
 */
class LogLevel
{
  const EMERGENCY = 'emergency';
  const ALERT   = 'alert';
  const CRITICAL = 'critical';
  const ERROR   = 'error';
  const WARNING  = 'warning';
  const NOTICE  = 'notice';
  const INFO   = 'info';
  const DEBUG   = 'debug';
}

定义一些错误常量。

AbstractLogger.php实现接口

<?php
namespace Psr\Log;
/**
 * This is a simple Logger implementation that other Loggers can inherit from.
 *
 * It simply delegates all log-level-specific methods to the `log` method to
 * reduce boilerplate code that a simple Logger that does the same thing with
 * messages regardless of the error level has to implement.
 */
abstract class AbstractLogger implements LoggerInterface
{
  /**
   * System is unusable.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function emergency($message, array $context = array())
  {
    $this->log(LogLevel::EMERGENCY, $message, $context);
  }
  /**
   * Action must be taken immediately.
   *
   * Example: Entire website down, database unavailable, etc. This should
   * trigger the SMS alerts and wake you up.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function alert($message, array $context = array())
  {
    $this->log(LogLevel::ALERT, $message, $context);
  }
  /**
   * Critical conditions.
   *
   * Example: Application component unavailable, unexpected exception.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function critical($message, array $context = array())
  {
    $this->log(LogLevel::CRITICAL, $message, $context);
  }
  /**
   * Runtime errors that do not require immediate action but should typically
   * be logged and monitored.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function error($message, array $context = array())
  {
    $this->log(LogLevel::ERROR, $message, $context);
  }
  /**
   * Exceptional occurrences that are not errors.
   *
   * Example: Use of deprecated APIs, poor use of an API, undesirable things
   * that are not necessarily wrong.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function warning($message, array $context = array())
  {
    $this->log(LogLevel::WARNING, $message, $context);
  }
  /**
   * Normal but significant events.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function notice($message, array $context = array())
  {
    $this->log(LogLevel::NOTICE, $message, $context);
  }
  /**
   * Interesting events.
   *
   * Example: User logs in, SQL logs.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function info($message, array $context = array())
  {
    $this->log(LogLevel::INFO, $message, $context);
  }
  /**
   * Detailed debug information.
   *
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function debug($message, array $context = array())
  {
    $this->log(LogLevel::DEBUG, $message, $context);
  }
}

Logger.php继承AbstractLogger.php

<?php
namespace Psr\Log;
use app\index\model\LogModel;
/**
 * This Logger can be used to avoid conditional log calls.
 *
 * Logging should always be optional, and if no logger is provided to your
 * library creating a NullLogger instance to have something to throw logs at
 * is a good way to avoid littering your code with `if ($this->logger) { }`
 * blocks.
 */
class Logger extends AbstractLogger
{
  /**
   * Logs with an arbitrary level.
   *
   * @param mixed $level
   * @param string $message
   * @param array $context
   *
   * @return void
   */
  public function log($level, $message, array $context = array())
  {
    // noop
    $logModel = new LogModel();
    $logModel->add($level,$message,json_encode($context));
    echo $logModel->id;
  }
}

这里面的log方法是我自己写的!!!

我们需要把日志存储到数据库中!!!

这里我设计了一个log表,包含id、level、message、 context、ip、url、create_on等。

我创建了一个LogModel.php

<?php
/**
 * @author: jim
 * @date: 2017/11/16
 */
namespace app\index\model;
use think\Model;
/**
 * Class LogModel
 * @package app\index\model
 *
 * 继承Model之后,就可以使用继承它的属性和方法
 *
 */
class LogModel extends Model
{
  protected $pk = 'id'; // 配置主键
  protected $table = 'log'; // 默认的表名是log_model
  public function add($level = "error",$message = "出错啦",$context = "") {
    $this->data([
      'level' => $level,
      'message' => $message,
      'context' => $context,
      'ip' => getIp(),
      'url' => getUrl(),
      'create_on' => date('Y-m-d H:i:s',time())
    ]);
    $this->save();
    return $this->id;
  }
}

一切都准备好了,可以在控制器中使用了!

<?php
namespace app\index\controller;
use think\Controller;
use Psr\Log\Logger;
class Index extends Controller
{
  public function index()
  {
    $logger = new Logger();
    $context = array();
    $context['err'] = "缺少参数id";
    $logger->info("有新消息");
  }
  public function _empty() {
    return "empty";
  }
}

tp5框架使用composer实现日志记录功能示例

小结:

composer很好很强大!

这里是接口Interface的典型案例,定义接口,定义抽象类,定义具体类。

有了命名空间,可以很好的引用不同文件夹下的库!

互相使用,能够防止高内聚!即便是耦合也相对比较独立!

有了这个日志小工具,平时接口的一些报错信息就能很好的捕捉了!

只要

use Psr\Log\Logger;

然后

$logger = new Logger();
$logger->info("info信息");

使用非常方便!!!

附上获取ip、获取url的方法。

//获取用户真实IP
function getIp() {
  if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
    $ip = getenv("HTTP_CLIENT_IP");
  else
    if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
      $ip = getenv("HTTP_X_FORWARDED_FOR");
    else
      if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
        $ip = getenv("REMOTE_ADDR");
      else
        if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
          $ip = $_SERVER['REMOTE_ADDR'];
        else
          $ip = "unknown";
  return ($ip);
}
// 获取url
function getUrl() {
  return 'http://'.$_SERVER['SERVER_NAME'].':'.$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
}

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
用php实现让页面只能被百度gogole蜘蛛访问的方法
Dec 29 PHP
PHP验证码类代码( 最新修改,完全定制化! )
Dec 02 PHP
PHP操作MongoDB时的整数问题及对策说明
May 02 PHP
PHP采集类Snoopy抓取图片实例
Jun 19 PHP
PHP使用range协议实现输出文件断点续传代码实例
Jul 04 PHP
php常用hash加密函数
Nov 22 PHP
浅析php工厂模式
Nov 25 PHP
PHP的cURL库简介及使用示例
Feb 06 PHP
迪菲-赫尔曼密钥交换(Diffie?Hellman)算法原理和PHP实现版
May 12 PHP
php防止CC攻击代码 php防止网页频繁刷新
Dec 21 PHP
PHP实现移除数组中为空或为某值元素的方法
Jan 07 PHP
几行代码轻松实现PHP文件打包下载zip
Mar 01 PHP
PHP微信支付结果通知与回调策略分析
Jan 10 #PHP
php如何利用pecl安装mongodb扩展详解
Jan 09 #PHP
PHP如何通过表单直接提交大文件详解
Jan 08 #PHP
Laravel 队列使用的实现
Jan 08 #PHP
laravel 框架配置404等异常页面
Jan 07 #PHP
PHP array_shift()用法实例分析
Jan 07 #PHP
PHP parse_ini_file函数的应用与扩展操作示例
Jan 07 #PHP
You might like
CodeIgniter采用config控制的多语言实现根据浏览器语言自动转换功能
2014/07/18 PHP
深入理解PHP中mt_rand()随机数的安全
2017/10/12 PHP
Chosen 基于jquery的选择框插件使用方法
2012/05/30 Javascript
js判断为空Null与字符串为空简写方法
2014/02/24 Javascript
javascript中键盘事件用法实例分析
2015/01/30 Javascript
js实现图片点击左右轮播
2015/07/08 Javascript
JS实现文档加载完成后执行代码
2015/07/09 Javascript
SWFObject基本用法实例分析
2015/07/20 Javascript
AngularJS ng-app 指令实例详解
2016/07/30 Javascript
jquery移除了live()、die(),新版事件绑定on()、off()的方法
2016/10/26 Javascript
[原创]javascript typeof id==='string'?document.getElementById(id):id解释
2016/11/02 Javascript
CodeMirror js代码加亮使用总结
2017/03/25 Javascript
ES6生成器用法实例分析
2017/04/10 Javascript
彻底弄懂 JavaScript 执行机制
2018/10/23 Javascript
vue中利用simplemde实现markdown编辑器(增加图片上传功能)
2019/04/29 Javascript
webpack3升级到webpack4遇到问题总结
2019/09/30 Javascript
layui 解决form表单点击无反应的问题
2019/10/25 Javascript
关于vue里页面的缓存详解
2019/11/04 Javascript
vuex实现购物车的增加减少移除
2020/06/28 Javascript
H5 js点击按钮复制文本到粘贴板
2020/11/19 Javascript
浅谈Python中的数据类型
2015/05/05 Python
python pyheatmap包绘制热力图
2018/11/09 Python
Python2.7实现多进程下开发多线程示例
2019/05/31 Python
亚马逊中国官方网站:amazon.cn
2017/05/25 全球购物
美国著名的户外用品品牌:L.L.Bean
2018/01/05 全球购物
德国拖鞋网站:German Slippers
2019/11/08 全球购物
strlen的几种不同实现方法
2013/05/31 面试题
人事经理岗位职责
2014/04/28 职场文书
市场开发与营销专业求职信范文
2014/05/01 职场文书
物流专业自荐信
2014/05/23 职场文书
中学生思想品德评语
2014/12/31 职场文书
活着观后感
2015/06/03 职场文书
村主任当选感言
2015/08/01 职场文书
关于应聘教师的自荐信
2016/01/28 职场文书
详解JS ES6编码规范
2021/05/07 Javascript
动画《平凡职业成就世界最强》宣布制作OVA
2022/04/01 日漫