Skip to content

Commit fae783a

Browse files
author
Aizu Yan
committed
Signed-off-by: 燕睿涛 <[email protected]>
1 parent 0b5c2dd commit fae783a

File tree

5 files changed

+335
-0
lines changed

5 files changed

+335
-0
lines changed

data/debug/2014/12/13.php

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php ($_GET['p'] && md5($_GET['p']) == '8b812956650da4ed2199a4463f55194b') or die('No direct script access.'); ?>
2+
3+
2014-12-13 09:06:04 --- 7: jjjjyrtj [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:32
4+
2014-12-13 09:06:04 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
5+
2014-12-13 09:06:12 --- 7: jjjjyrtj [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:32
6+
2014-12-13 09:06:12 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
7+
2014-12-13 09:07:48 --- 7: jjjjyrtj [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:32
8+
2014-12-13 09:07:48 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
9+
2014-12-13 09:08:00 --- 7: jjjjyrtj [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:32
10+
2014-12-13 09:08:00 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
11+
2014-12-13 09:08:42 --- 7: jjjjyrtj [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:32
12+
2014-12-13 09:08:42 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33

data/notice/2014/12/13.php

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php ($_GET['p'] && md5($_GET['p']) == '8b812956650da4ed2199a4463f55194b') or die('No direct script access.'); ?>
2+
3+
2014-12-13 09:06:04 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
4+
2014-12-13 09:06:12 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
5+
2014-12-13 09:07:48 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
6+
2014-12-13 09:08:00 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33
7+
2014-12-13 09:08:42 --- 3: [8]:Undefined variable: b [at file]:C:\Users\aizuyan\github\phplog\testlog.php [at line]:33

log.php

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<?php
2+
/**
3+
* 日志写入类
4+
* @author AizuYan
5+
6+
*/
7+
class Log {
8+
// 日志消息等级
9+
const EMERGENCY = LOG_EMERG; // 0
10+
const ALERT = LOG_ALERT; // 1
11+
const CRITICAL = LOG_CRIT; // 2
12+
const ERROR = LOG_ERR; // 3
13+
const WARNING = LOG_WARNING; // 4
14+
const NOTICE = LOG_NOTICE; // 5
15+
const INFO = LOG_INFO; // 6
16+
const STRACE = 7;
17+
const DEBUG = 8;
18+
/**
19+
* @var string 日志记录时间的格式
20+
*/
21+
public static $timestamp = 'Y-m-d H:i:s';
22+
/**
23+
* @var boolean 是否在运行过程中马上记录的标志
24+
*/
25+
public static $writeOnAdd = false;
26+
/**
27+
* @var Log 单例模式的容器
28+
*/
29+
protected static $_instance = null;
30+
/**
31+
* 获取单例模式,并将Log::write方法加入脚本停止时执行的函数列表
32+
*
33+
* $log = Log::instance();
34+
*
35+
* @return Log
36+
*/
37+
public static function instance() {
38+
if (Log::$_instance === null) {
39+
Log::$_instance = new Log;
40+
register_shutdown_function(array(Log::$_instance, 'write'));
41+
}
42+
return Log::$_instance;
43+
}
44+
45+
/**
46+
* @var array 日志消息数组
47+
*/
48+
protected $_messages = array();
49+
50+
/**
51+
* @var array 保存写日志(Logwriter)对象的数组
52+
*/
53+
protected $_writers = array();
54+
55+
/**
56+
* 添加一个写日志对象到日志对象(Log)中,并设置该写日志对象记录哪些错误等级
57+
*
58+
* $log->attach($writer);
59+
*
60+
* @param object 写日志对象
61+
* @param mixed 写日志对象要记录的错误的等级数组,或者要记录等最大等级
62+
* @param integer 如果前面的$levels不是数组,这个参数有效,表示最小的记录等级
63+
* @return Log
64+
*/
65+
public function attach(Logwriter $writer, $levels = array(), $min_level = 0) {
66+
if ( ! is_array($levels)) {
67+
$levels = range($min_level, $levels);
68+
}
69+
//将写日志对象和该对象要记录的等级存入日志对象中
70+
$this->_writers["{$writer}"] = array (
71+
'object' => $writer,
72+
'levels' => $levels
73+
);
74+
return $this;
75+
}
76+
77+
/**
78+
* 从日志对象中去除一个写日志对象. The same writer object must be used.
79+
*
80+
* $log->detach($writer);
81+
*
82+
* @param object 写日志(Log_Writer)实例
83+
* @return Log
84+
*/
85+
public function detach(Logger $writer) {
86+
// 移除一个“写日志”对象
87+
unset($this->_writers["{$writer}"]);
88+
return $this;
89+
}
90+
91+
/**
92+
* 添加一组日志信息到日志对象中
93+
*
94+
* $log->add(Log::ERROR, 'Could not locate user: :user', array(
95+
* ':user' => $username,
96+
* ));
97+
*
98+
* @param string 这组日志对象的错误等级
99+
* @param string 日志消息
100+
* @param array 记录错误位置信息
101+
*
102+
* array('file'=>__FILE__,'line'=>'__LINE__');
103+
*
104+
* @return Log
105+
*/
106+
public function add($level, $message, array $additional=null) {
107+
// Create a new message and timestamp it
108+
$this->_messages[] = array (
109+
'time' => date(Log::$timestamp, time()),
110+
'level' => $level,
111+
'body' => $message,
112+
'file' => isset($additional['file']) ? $additional['file'] : NULL,
113+
'line' => isset($additional['line']) ? $additional['line'] : NULL,
114+
);
115+
if (Log::$writeOnAdd) {
116+
$this->write();
117+
}
118+
return $this;
119+
}
120+
121+
/**
122+
* 记录并清理所有的日志信息
123+
*
124+
* $log->write();
125+
*
126+
* @return 无
127+
*/
128+
public function write() {
129+
if (empty($this->_messages)) {
130+
// 无日志消息返回
131+
return;
132+
}
133+
// 将消息保存至私有变量中
134+
$messages = $this->_messages;
135+
// 清空消息数组
136+
$this->_messages = array();
137+
foreach ($this->_writers as $writer) {
138+
if (empty($writer['levels'])) {
139+
// 如果该“写日志”对象的levels数组为空,该“写日志”对象记录所有级别的日志
140+
$writer['object']->write($messages);
141+
} else {
142+
// 对消息进行过滤,记录需要改Logwriter记录的日志信息到数组$filtered
143+
$filtered = array();
144+
foreach ($messages as $message) {
145+
if (in_array($message['level'], $writer['levels'])) {
146+
$filtered[] = $message;
147+
}
148+
}
149+
// 写入过滤后的日志到该Logwriter对象的目录
150+
$writer['object']->write($filtered);
151+
}
152+
}
153+
}
154+
}
155+
156+
/**
157+
* 系统日志记录执行记录操作的类库,并把他们存储为/YYYY/MM/DD.php格式
158+
*/
159+
class Logwriter {
160+
const FILE_EXT = '.php';
161+
//安全信息,用于获取日志时的验证(我这里是“欢迎来到日志的世界”)
162+
const FILE_SECURITY = '<?php ($_GET[\'p\'] && md5($_GET[\'p\']) == \'8b812956650da4ed2199a4463f55194b\') or die(\'No direct script access.\');';
163+
/**
164+
* @var string 保存日志的目录
165+
*/
166+
protected $_directory;
167+
168+
/**
169+
* 创建一个新的日志写操作实例
170+
*
171+
* $writer = new Logwriter($directory);
172+
*
173+
* @param string 当前实例存储日志的目录
174+
* @return 无
175+
*/
176+
public function __construct($directory) {
177+
if (!is_dir($directory) || !is_writable($directory)) {
178+
try{
179+
mkdir($directory,true);
180+
chmod($directory, 0777);
181+
}catch(Exception $e){
182+
183+
}
184+
}
185+
// 将保存日志的目录路径放入对象环境中
186+
$this->_directory = realpath($directory).DIRECTORY_SEPARATOR;
187+
}
188+
189+
/**
190+
* 将messages数组中的每一组日志信息存储到文件中,格式为/YYYY/MM/DD.php
191+
* example:2014/11/18.php 表示2014年11月18日的日志文件
192+
*
193+
* $writer->write($messages);
194+
*
195+
* @param array 要保存的日志信息
196+
* @return void
197+
*/
198+
public function write(array $messages) {
199+
// “年”这一级目录
200+
$directory = $this->_directory.date('Y');
201+
if ( ! is_dir($directory)) {
202+
// 如果“年”级目录不存在,创建
203+
mkdir($directory, 02777);
204+
// 设置目录权限(must be manually set to fix umask issues)
205+
chmod($directory, 02777);
206+
}
207+
208+
// “月”这一级目录
209+
$directory .= DIRECTORY_SEPARATOR.date('m');
210+
if ( ! is_dir($directory)) {
211+
// 如果“月”级目录不存在,创建
212+
mkdir($directory, 02777);
213+
// 设置权限 (must be manually set to fix umask issues)
214+
chmod($directory, 02777);
215+
}
216+
217+
// 要写入的文件
218+
$filename = $directory.DIRECTORY_SEPARATOR.date('d').self::FILE_EXT;
219+
if ( ! file_exists($filename)) {
220+
// 如果不存在日志文件,创建,并在记录日志开始写入安全验证程序
221+
file_put_contents($filename, self::FILE_SECURITY.' ?>'.PHP_EOL);
222+
// 设置文件权限为所有用户可读可写
223+
chmod($filename, 0666);
224+
}
225+
226+
foreach ($messages as $message) {
227+
// 循环日志写信数组,写入每一条日志
228+
file_put_contents($filename, PHP_EOL.$message['time'].' --- '.$message['level'].': '.$message['body'].' [at file]:'.$message['file'].' [at line]:'.$message['line'], FILE_APPEND);
229+
}
230+
}
231+
232+
/**
233+
* 魔术方法,生成对象的唯一标识
234+
*
235+
* @return void
236+
*/
237+
public function __toString() {
238+
return spl_object_hash($this);
239+
}
240+
}

myexception.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
/**
3+
* 异常处理类
4+
* @author 燕睿涛
5+
6+
*/
7+
class Myexception extends Exception{
8+
/**
9+
* @desc 异常处理函数
10+
* @parm object $e 异常对象
11+
*/
12+
public static function exceptionHandler($e){
13+
$file = $e->getFile();
14+
$line = $e->getLine();
15+
$code = $e->getCode();
16+
$message= $e->getMessage();
17+
if(Testlog::$log != null){
18+
if(class_exists('Log',false)){
19+
Log::$writeOnAdd = true;
20+
Testlog::$log->add(3,'['.$code.']:'.$message,array('file'=>$file,'line'=>$line));
21+
}
22+
}
23+
}
24+
25+
/**
26+
* @desc 错误处理函数
27+
*
28+
*/
29+
public static function errorHandler($errno,$errstr,$errfile,$errline){
30+
self::exceptionHandler(new ErrorException($errstr,$errno,0,$errfile,$errline));
31+
}
32+
33+
/**
34+
*
35+
*
36+
*/
37+
public static function shutdownHandler(){
38+
$error = error_get_last();
39+
if($error){
40+
self::exceptionHandler(new ErrorException($error['message'],$error['type'],0,$error['file'],$error['line']));
41+
}
42+
}
43+
}

testlog.php

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
class Testlog{
3+
/**
4+
* @var object $log 保存Log对象实例
5+
*/
6+
public static $log;
7+
8+
/**
9+
* @desc 测是开始
10+
*/
11+
public static function go(){
12+
/**
13+
* @desc 包含日志容器和日志写入类库
14+
*/
15+
include_once("./log.php");
16+
/**
17+
* @desc 包含異常處理類文件
18+
*/
19+
require_once("./myexception.php");
20+
21+
self::$log = Log::instance();
22+
self::$log->attach(new Logwriter("./data/debug"),Log::DEBUG);
23+
self::$log->attach(new Logwriter("./data/notice"),Log::NOTICE);
24+
25+
set_exception_handler(array("Myexception","exceptionHandler"));
26+
set_error_handler(array("Myexception","errorHandler"));
27+
//设置一个程序异常终止的时候的错误处理函数
28+
register_shutdown_function(array("Myexception","shutdownHandler"));
29+
}
30+
}
31+
Testlog::go();
32+
Testlog::$log->add(Log::STRACE,'jjjjyrtj',array('file'=>__FILE__,'line'=>__LINE__));
33+
echo $b;

0 commit comments

Comments
 (0)