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实现框架(一)
Oct 09 PHP
坏狼的PHP学习教程之第2天
Jun 15 PHP
php 正则匹配函数体
Aug 25 PHP
PHP 如何利用phpexcel导入数据库
Aug 24 PHP
php自动加载autoload机制示例分享
Feb 20 PHP
PHP采用自定义函数实现遍历目录下所有文件的方法
Aug 19 PHP
Yii框架登录流程分析
Dec 03 PHP
PHP动态输出JavaScript代码实例
Feb 12 PHP
浅析Yii2集成富文本编辑器redactor实例教程
Apr 25 PHP
PHP面向对象五大原则之开放-封闭原则(OCP)详解
Apr 04 PHP
PHP超级全局变量【$GLOBALS,$_SERVER,$_REQUEST等】用法实例分析
Dec 11 PHP
php操作redis数据库常见方法实例总结
Feb 20 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
php 购物车实例(申精)
2009/05/11 PHP
Redis使用Eval多个键值自增的操作实例
2016/11/04 PHP
Swoole源码中如何查询Websocket的连接问题详解
2020/08/30 PHP
js封装的textarea操作方法集合(兼容很好)
2010/11/16 Javascript
jQuery lazyload 的重复加载错误以及修复方法
2010/11/19 Javascript
js中的string.format函数代码
2020/08/11 Javascript
jQuery响应enter键的实现思路
2014/04/18 Javascript
使用typeof判断function是否存在于上下文
2014/08/14 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
javascript的BOM
2016/05/03 Javascript
jquery.multiselect多选下拉框实现代码
2016/11/11 Javascript
JS实现“隐藏与显示”功能(多种方法)
2016/11/24 Javascript
基于jQuery实现的幻灯图片切换
2016/12/02 Javascript
jQuery插件zTree实现获取一级节点数据的方法
2017/03/08 Javascript
canvas实现爱心和彩虹雨效果
2017/03/09 Javascript
微信小程序页面生命周期详解
2018/01/31 Javascript
vue 组件中slot插口的具体用法
2018/04/03 Javascript
JavaScript使用Math.random()生成简单的验证码
2019/01/21 Javascript
小程序如何定位所在城市及发起周边搜索
2020/02/11 Javascript
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
DataFrame:通过SparkSql将scala类转为DataFrame的方法
2019/01/29 Python
python的sorted用法详解
2019/06/25 Python
TensorFlow查看输入节点和输出节点名称方式
2020/01/04 Python
基于python SMTP实现自动发送邮件教程解析
2020/06/02 Python
Python中关于logging模块的学习笔记
2020/06/03 Python
JD Sports芬兰:英国领先的运动鞋和运动服饰零售商
2018/11/16 全球购物
班级安全教育实施方案
2014/02/23 职场文书
自我鉴定书
2014/03/24 职场文书
淘宝店策划方案
2014/06/07 职场文书
幼儿园标语大全
2014/06/19 职场文书
毕业横幅标语
2014/10/08 职场文书
机关保密工作承诺书
2015/05/04 职场文书
王亚平太空授课观后感
2015/06/12 职场文书
2019年二手房买卖合同范本
2019/10/14 职场文书
python数字类型和占位符详情
2022/03/13 Python
Win11无法访问设备和打印机 如何解决页面空白
2022/04/09 数码科技