本文实例讲述了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\"]; }
更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《thinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》、《codeigniter入门教程》、《CI(CodeIgniter)框架进阶教程》、《Zend FrameWork框架入门教程》及《PHP模板技术总结》。
希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。
暂无评论内容