最近在做的一个项目,由于全是通过远程HTTP请求来调用PHP的接口程序。

接收到的参数和返回的内容对开发人员来说都是未知不可见的。

虽然可以通过直接在脚本中模拟请求,但由于实际环境复杂的多,调试极其不方便。

于是想是否可以写一个函数用来记录对PHP接口调用的情况。

想到以前看到过的一个PHP函数 register_shutdown_function()

该函数的作用是注册一个函数,当PHP脚本执行完成,或者代码中调用了 exit , die 这样的代码之后,执行预先注册好的函数。
这样我们就可以在该函数中记录PHP调用执行的情况了。

简单写了下,看起来应该可以用了:

<?php
function bdebug(){ $file = "bdebug_log.txt"; if ($_REQUEST){
foreach ($_REQUEST as $k => $v) {
$request .= $k . " = " . $v . "
";
}
} foreach ($_SERVER as $k => $v) {
$server .= $k . " = " . $v . "
";
} $content = date('Y-m-d H:i:s') . " REQUEST信息:
" . $request . "
SERVER信息:
" . $server . "
"; ob_start(); function shutdown_func($file){
$content = date('Y-m-d H:i:s') . " 输出的信息:
" . ob_get_contents() . "
";
file_put_contents($file, $content, FILE_APPEND);
} register_shutdown_function('shutdown_func', dirname(__FILE__) . DIRECTORY_SEPARATOR . $file);
file_put_contents($file, $content, FILE_APPEND);
}
?>

PHP中非期望致命错误的另一种处理方式:register_shutdown_function()

程序员正确的逻辑,和良好的编程风格,对一段代码实现来说是非常重要的,既能最大限度地保证程序的准确运行,也可以在出现错误时便于调试。但也有一些意外情况的出现,导致了代码运行得到非期望的结果。当然,一些健壮的语言可以有很好的异常处理机制,比如java,但我这里要说的是在使用php进行web开发的过程中遇到的一点小问题。

日前自己参考wordpress摆弄了一个极其简易的blog程序,在实现文章编辑成功,并相指定地址发送pingback的时候,出了点小故障。期望结果是完成以上操作后,定向到文章列表页面。而出现的意外情况是,当指定的地址不可用(目标地址服务器不可访问)时,产生了一个致命错误,返回页面是错误信息,并没有如期望的跳转到文章列表。

显然,程序的健壮性不够,没有考虑到上面的异常情况。发送pingback的功能使用了php提供的套接字连接函数,在后来的测试时,若目标主机不存在,并不会导致致命错误,只是一个警告,而让人困惑的是先前的测试却出现了致命错误,可能是我修改了某些php配置引起的吧(调整了一些模块)。对于这种情况,一般用错误抑止符就可以忽略了错误信息的输出。而我想知道wordpress的处理方式是怎样的,读了它的这段实现代码后,发现其做法是在套接字连接函数前加了错误抑止符,另外将发送pingback的函数通过register_shutdown_function()注册为请求结束时的动作。这一做法给了我以启示,在php手册中,关于register_shutdown_function()函数的说明中,有这么一段注解:

Typically undefined functions cause fatal errors in PHP, but when the function called with register_shutdown_function() is undefined, an error of level E_WARNING is generated instead. Also, for reasons internal to PHP, this error will refer to Unknown() at line #0.

我们不妨将其理解为该函数可以让致命错误降级,而函数说明中有如下描述:

The registered shutdown functions are called after the request has been completed (including sending any output buffers), so it is not possible to send output to the browser using echo() or print(), or retrieve the contents of any output buffers using ob_get_contents().

那么我们就可以使用这个函数来实现类似‘@’抑止错误信息的效果了。

当然,使用这个函数来处理一些错误信息可能是得不偿失,因为这个函数的用途的初衷并不是这样的,而且,我也未能测试其执行效率,在此只是尝试另一种思路而已。

手册中还有一段说明:PHP 3 或者 PHP 4 中都没有析构函数。你可以使用 register_shutdown_function() 函数来模拟析构函数的效果。我想,这才是物尽其用吧!

如:

<?php
class Template { // 属性 public function __construct() {
// ......
if (version_compare(PHP_VERSION, '5') == -1) {
register_shutdown_function(array(&$this, '__destruct'));
}
} /**
* 析构函数
*/
public function __destruct() {
if($_COOKIE['sid']) {
return;
}
$sid = rawurlencode($this->sid);
$searcharray = array(
"/<a(s*[^>]+s*)href=(["|']?)([^"'s]+)/ies",
"/(<form.+?>)/is"
);
$replacearray = array(
"$this->_transSid('\3','<a\1href=\2')",
"\1
<input type="hidden" name="sid" value="".rawurldecode(rawurldecode(rawurldecode($sid)))."" />"
);
$content = preg_replace($searcharray, $replacearray, ob_get_contents());
ob_end_clean(); echo $content;
}
}

利用PHP的register_shutdown_function来记录PHP的输出日志,模拟析构函数的更多相关文章

  1. 利用php的register_shutdown_function来记录php的输出日志

    最近在做的一个项目..由于全是通过远程http请求来调用php的接口程序.. 接收到的参数和返回的内容对开发人员来说都是未知不可见的.. 虽然可以通过直接在脚本中模拟请求..但由于实际环境复杂的多.. ...

  2. MySQL 使用tee记录语句和输出日志

    在mysql命令行中,使用tee命令,可以记录语句和输出到指定文件.在debugging时会很有用.每执行一条语句,mysql都会讲执行结果刷新到指定文件.Tee功能只在交互模式生效. mysql&g ...

  3. Java中使用Log4j记录错误、输出日志

    简介: Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务器.NT的事件记录器.UNIX Syslog守护进 ...

  4. "利用python进行数据分析"学习记录01

    "利用python进行数据分析"学习记录 --day01 08/02 与书相关的资料在 http://github.com/wesm/pydata-book pandas 的2名字 ...

  5. 利用Python中的mock库对Python代码进行模拟测试

    这篇文章主要介绍了利用Python中的mock库对Python代码进行模拟测试,mock库自从Python3.3依赖成为了Python的内置库,本文也等于介绍了该库的用法,需要的朋友可以参考下     ...

  6. 记录Windows远程登录日志(转)

    1.建立一个名为RDPlog.bat的批处理文件,内容为: echo @offdate /t >>Z:\IIS\RDPlog.txt time /t >>Z:\IIS\RDPl ...

  7. 【记录】尝试用QEMU模拟ARM开发板去加载并运行Uboot,kernel,rootfs【转】

    转自:https://www.crifan.com/try_use_qemu_emulate_arm_board_to_load_and_run_uboot_kernel_rootfs/ [背景] 手 ...

  8. 让FIREDAC记录数据库的异常日志

    默认FIREDAC不会记录数据库的异常. 比如典型的,提交的时候,非空字段没有给值. 某些人还以为FIREDAC不能捕获数据库的异常,其实FIREDAC是可以捕获并处理数据库的异常事件的. 方法异常简 ...

  9. python学习记录_中断正在执行的代码,执行剪切板中的代码,键盘快捷键,魔术命令,输入和输出变量,记录输入和输出变量_

    2018-03-28 00:56:39 中断正在执行的代码 无论是%run执行的脚本还是长时间运行的命令ctrl + cIn [1]: KeyboardInterrupt 执行剪切板中的代码 ctrl ...

随机推荐

  1. js/jquery/html前端开发常用到代码片段

    1.IE条件注释 条件注释简介 IE中的条件注释(Conditional comments)对IE的版本和IE非IE有优秀的区分能力,是WEB设计中常用的hack方法.条件注释只能用于IE5以上,IE ...

  2. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Stat ...

  3. 3.开发Java消息驱动bean实例代码

    java消息服务(JMS)是用于访问企业消息系统的开发商中立的API.企业消息系统可以协助应用软件通过网络进行消息交互.应用程序A发送一条消息到消息服务器的某个目的地(Destination),然后消 ...

  4. JSON 字符串中的中括号和大括号区别详解

    json 变量有两种可能, 可能是一个对象, (类似 类的实例), 也可能是一个数组!! 主要是要 从 ""语义" 上来分析, 到底该用 大括号还是用中括号: 如果从语义 ...

  5. Spring框架总结

    Spring(由Rod Johnson创建的一个开源框架) Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建.简单来说,Spr ...

  6. GHOST急速安装win10或win7

    首先说说写这篇博客的原因,我自己曾经被装各种系统弄得焦头烂额,各种刻光盘光驱安装,写优盘安装以及pe盘恢复系统等等,每次都各种方式尝试一下,太浪费时间了,所以天真的想着能不能有一个类似"一劳 ...

  7. Win7下mysql root账户登录提示:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)解决方案

    ERROR 1045 (28000): Ac-- password: YES)这个意思是密码不正确,那就修改密码: 如果你是服务器是 windows xp/2000/2003/nt 都可以使用这个方法 ...

  8. Quartz Cron表达式 在线生成器

    Cron Expressions——Cron 表达式 按顺序依次为 秒(0~59) 分钟(0~59) 小时(0~23) 天(月)(0~31,但是你需要考虑你月的天数) 月(0~11) 天(星期)(1~ ...

  9. Python2.7.6标准库内建函数

        Built-in Functions     abs() divmod() input() open() staticmethod() all() enumerate() int() ord( ...

  10. viewport就是这回事

    前言 对于移动webapp开发人员来说,viewport是个很重要的东西,容易用但很多时候都是不明白的,于是我决心去弄清楚它. <meta name="viewport" c ...