本文實例講述了tp5框架使用composer實現(xiàn)日志記錄功能。分享給大家供大家參考,具體如下:
tp5實現(xiàn)日志記錄
1.安裝 psr/log
它的作用就是提供一套接口,實現(xiàn)正常的日志功能!
我們可以來細細的分析一下,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());
}
這是一套日志正常的接口,有層級,有消息,有具體的內(nèi)容。
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實現(xiàn)接口
?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方法是我自己寫的!?。?/p>
我們需要把日志存儲到數(shù)據(jù)庫中?。。?/p>
這里我設(shè)計了一個log表,包含id、level、message、 context、ip、url、create_on等。
我創(chuàng)建了一個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'] = "缺少參數(shù)id";
$logger->info("有新消息");
}
public function _empty() {
return "empty";
}
}
小結(jié):
composer很好很強大!
這里是接口Interface的典型案例,定義接口,定義抽象類,定義具體類。
有了命名空間,可以很好的引用不同文件夾下的庫!
互相使用,能夠防止高內(nèi)聚!即便是耦合也相對比較獨立!
有了這個日志小工具,平時接口的一些報錯信息就能很好的捕捉了!
只要
然后
$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"];
}
更多關(guān)于thinkPHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《ThinkPHP入門教程》、《thinkPHP模板操作技巧總結(jié)》、《ThinkPHP常用方法總結(jié)》、《codeigniter入門教程》、《CI(CodeIgniter)框架進階教程》、《Zend FrameWork框架入門教程》及《PHP模板技術(shù)總結(jié)》。
希望本文所述對大家基于ThinkPHP框架的PHP程序設(shè)計有所幫助。
您可能感興趣的文章:- Laravel框架中composer自動加載的實現(xiàn)分析
- PHP管理依賴(dependency)關(guān)系工具 Composer的自動加載(autoload)
- Laravel 解決composer相關(guān)操作提示php相關(guān)異常的問題
- laravel 實現(xiàn)向公共模板中傳值 (view composer)
- 淺談laravel 5.6 安裝 windows上使用composer的安裝過程
- 使用composer 安裝 laravel框架的方法圖文詳解
- 一次因composer錯誤使用引發(fā)的問題與解決
- windows環(huán)境下使用Composer安裝ThinkPHP5
- PHP創(chuàng)建自己的Composer包方法
- 分析Composer實現(xiàn)自動加載原理