我是靠谱客的博主 魁梧微笑,最近开发中收集的这篇文章主要介绍使用register_shutdown_function实现php项目脚本执行失败的实时报警,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
背景:当线上php脚本执行失败时,希望能够实时地自动发送报警邮件,而不是等收到用户的反馈才知道有bug存在。
分析:
当我们的php脚本正常执行完成或意外死掉导致PHP执行即将结束
时,
register_shutdown_function指定的函数
将会被调用。
实现思路:
在脚本开始处设置一个变量,值为false,然后在脚本末尾将之设置为true,让PHP关闭回调函数(即我们指定的函数)检查脚本是否已经完成【如果我们的变量仍旧是false,我们就知道脚本的最后一行没有执行,因此它肯定在程序执行到某处死掉了】
以下是一个演示例子:
1、主入口index.php文件:
<?php
// start
function shutdown_func() { //定义关闭回调函数
// shutdown
global
$completeFlag
;
global $completeFlagKey ;
if ( ! $completeFlag) {
$monitorVal = 'URL地址:' . $_SERVER[ 'REQUEST_URI'] . '<br>' ;
$monitorVal .= 'GET参数:' .json_encode( $_GET) . '<br>' ;
global $completeFlagKey ;
if ( ! $completeFlag) {
$monitorVal = 'URL地址:' . $_SERVER[ 'REQUEST_URI'] . '<br>' ;
$monitorVal .= 'GET参数:' .json_encode( $_GET) . '<br>' ;
$monitorVal .= 'POST参数:'.json_encode($_POST).'<br>';
$monitorVal
.=
'当前用户:'
.
$_SESSION[
'currUserName']
.
'<br>'
;
$monitorVal
.=
'时间:'
.date(
'Y-m-d H:i:s')
.
'<br>'
;
$monitorVal .= '错误信息:' .json_encode( error_get_last()) ;
$redis = new Redis() ;
$redis ->connect( '127.0.0.1' , 6379) ;
$redis ->set( $completeFlagKey , $monitorVal) ;
}
return false ;
$monitorVal .= '错误信息:' .json_encode( error_get_last()) ;
$redis = new Redis() ;
$redis ->connect( '127.0.0.1' , 6379) ;
$redis ->set( $completeFlagKey , $monitorVal) ;
}
return false ;
}
register_shutdown_function("shutdown_func");
$completeFlag
=
false
;
$completeFlagKey = uniqid('scriptShutdownMonitor_');
/*...这里是其他功能代码...*/
$completeFlag = true;
// end
?>
2、各控制器都集成CommonController,
CommonController文件的析构函数:
function __destruct() {
// destruct
global
$g_curr_run_env
;
global $completeFlagKey ;
if ( $g_curr_run_env == 'online') {
$redis = new Redis() ;
$redis ->connect( '127.0.0.1' , 6379) ;
$redis ->delete( $completeFlagKey) ;
}
}
global $completeFlagKey ;
if ( $g_curr_run_env == 'online') {
$redis = new Redis() ;
$redis ->connect( '127.0.0.1' , 6379) ;
$redis ->delete( $completeFlagKey) ;
}
}
注意:__destruct里面如果要操作文件,也要写绝对路径
(1)如果是正常运行完,执行流程为:
start 代码 destruct end
shutdown
(2)如果是脚本发生error,执行流程为:
start 代码 shutdown
(3)如果是代码里面主动exit()或die(),执行流程为:start 代码 s
hutdown
destruct
3、监控报警邮件。通过crontab定时调用
set_time_limit
(
0
)
;
date_default_timezone_set ( ' Asia/shanghai ' ) ;
$ redis = new Redis () ;
$ redis -> connect ( ' 127.0.0.1 ', 6379 ) ;
$ keys = $ redis -> keys ( ' scriptShutdownMonitor_* ' ) ;
$ msg = "";
foreach ( $ keys as $ key ) {
$ val = $ redis -> get ( $ key ) ;
if ( $ val ) {
$ msg .= $ val . " <br><hr><br> ";
}
$ redis -> del ( $ key ) ;
}
if ( $ msg != '' ) {
$ logCon = " 当前时间: " . date ( ' Y-m-d H:i:s ' ) . " ;msg: " .$ msg . " n ";
file_put_contents ( " send_email.log ", $ logCon , FILE_APPEND ) ;
require_once( ' send_email.php ' ) ;
date_default_timezone_set ( ' Asia/shanghai ' ) ;
$ redis = new Redis () ;
$ redis -> connect ( ' 127.0.0.1 ', 6379 ) ;
$ keys = $ redis -> keys ( ' scriptShutdownMonitor_* ' ) ;
$ msg = "";
foreach ( $ keys as $ key ) {
$ val = $ redis -> get ( $ key ) ;
if ( $ val ) {
$ msg .= $ val . " <br><hr><br> ";
}
$ redis -> del ( $ key ) ;
}
if ( $ msg != '' ) {
$ logCon = " 当前时间: " . date ( ' Y-m-d H:i:s ' ) . " ;msg: " .$ msg . " n ";
file_put_contents ( " send_email.log ", $ logCon , FILE_APPEND ) ;
require_once( ' send_email.php ' ) ;
send_email(
'xx@qq.com',
'
线上脚本执行失败报警
',
$
msg
)
;
}
附上博主的个人网站:
w3cstudy学习网,上面的有很多供学习文章,有兴趣可以去逛逛
几点说明:
1、 register_shutdown_function('
shutdown_func
');
对应回调函数的定义以及这句话要放在有可能引发错误的代码前面,否则在错误代码处崩溃后,这行代码也不会执行
参数:可以是一个字符串,即指定的关闭回调函数的名称,无需带括号,用引号包住即可; 也可以是一个数组,如array(
‘
error
’
,
’
shutdown_errow
’
)表示指定error类中的shutdown_error函数为关闭回调函数。
2、exit();//即使使用了exit();也会在exit()执行完后调用register_shutdown_function函数!
3、register_shutdown_function执行机制是:
php把要调用的函数调入内存。当页面所有php语句都执行完成时,再调用此函数。注意,在这个时候从内存中调用,不是从php页面中调用,所以上面的例子中回调函数内如果要操作文件不能使用相对路径,因为php已经当原来的页面不存在了。就没有什么相对路 径可言。
4、可以这样理解调用条件:
(1)当页面被用户代码如exit()强制停止时
(2)当程序代码运行超时或者出现错误时
(3)当php代码正常执行完成时
最后
以上就是魁梧微笑为你收集整理的使用register_shutdown_function实现php项目脚本执行失败的实时报警的全部内容,希望文章能够帮你解决使用register_shutdown_function实现php项目脚本执行失败的实时报警所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复