php教程

超轻量级php框架startmvc

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

更新时间:2020-04-02 01:36:59 作者:startmvc
本文实例讲述了tp5框架使用composer实现日志记录功能。分享给大家供大家参考,具体如下:t

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

tp5实现日志记录

1.安装 psr/log


composer require psr/log

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

我们可以来细细的分析一下,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";
 }
}

小结:

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"];
}

tp5框架 composer 日志记录