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
超强分页类2.0发布,支持自定义风格,默认4种显示模式
Jan 02 PHP
php 读取文件乱码问题
Feb 20 PHP
php中DOMElement操作xml文档实例演示
Mar 26 PHP
phpcms模块开发之swfupload的使用介绍
Apr 28 PHP
PHP生成自适应大小的缩略图类及使用方法分享
May 06 PHP
PHP使用GIFEncoder类处理gif图片实例
Jul 01 PHP
PHP图形操作之Jpgraph学习笔记
Dec 25 PHP
PHP使用php-resque库配合Redis实现MQ消息队列的教程
Jun 29 PHP
PHP实现微信红包金额拆分试玩的算法示例
Apr 07 PHP
php实现往pdf中加数字签名操作示例【附源码下载】
Aug 07 PHP
laravel实现按时间日期进行分组统计方法示例
Mar 23 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
dedecms后台验证码总提示错误的解决方法
2007/03/21 PHP
php 进度条实现代码
2009/03/10 PHP
php 购物车实例(申精)
2009/05/11 PHP
php 操作excel文件的方法小结
2009/12/31 PHP
php根据年月获取季度的方法
2014/03/31 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
php实现在新浪云中使用imagick生成缩略图并上传的方法
2016/09/26 PHP
什么是PHP文件?如何打开PHP文件?
2017/06/27 PHP
php判断str字符串是否是xml格式数据的方法示例
2017/07/26 PHP
JavaScript去除空格的几种方法
2006/10/03 Javascript
js 操作css实现代码
2009/06/11 Javascript
表单JS弹出填写提示效果代码
2011/04/16 Javascript
js 窗口抖动示例
2013/09/04 Javascript
js同比例缩放图片的小例子
2013/10/30 Javascript
IE8下String的Trim()方法失效的解决方法
2013/11/08 Javascript
JavaScript DOM节点添加示例
2014/07/16 Javascript
HTML+CSS+JS实现完美兼容各大浏览器的TABLE固定列
2015/04/26 Javascript
jQuery平滑旋转幻灯片特效代码分享
2015/09/07 Javascript
javascript函数自动执行常用方法汇总
2016/03/28 Javascript
js 判断登录界面的账号密码是否为空
2017/02/08 Javascript
vue.js 实现点击展开收起动画效果
2018/07/07 Javascript
vue动画之点击按钮往上渐渐显示出来的实例
2018/09/29 Javascript
微信小程序开发技巧汇总
2019/07/15 Javascript
vue实现路由不变的情况下,刷新页面操作示例
2020/02/02 Javascript
Python操作word常见方法示例【win32com与docx模块】
2018/07/17 Python
python xpath获取页面注释的方法
2019/01/14 Python
python读csv文件时指定行为表头或无表头的方法
2019/06/26 Python
python 实现非极大值抑制算法(Non-maximum suppression, NMS)
2020/10/15 Python
python安装第三方库如xlrd的方法
2020/10/31 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
CAT鞋加拿大官网:CAT Footwear加拿大
2020/08/05 全球购物
市场推广策划方案
2014/06/02 职场文书
大明湖导游词
2015/02/03 职场文书
贷款收入证明格式
2015/06/24 职场文书
2019旅游导游工作总结
2019/06/27 职场文书
两行代码解决Jupyter Notebook中文不能显示的问题
2021/04/24 Python