最近在做的一个项目,由于全是通过远程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. C#中使用FreeImage库加载Bmp、JPG、PNG、PCX、TGA、PSD等25种格式的图像(源码)。

    其实我一直都是喜欢自己去做图像格式的解码的(目前我自己解码的图像格式大概有15种),但是写本文主要原因是基于CSDN的这个帖子的: http://bbs.csdn.net/topics/3905104 ...

  2. 第3章 Linux常用命令(3)_文件搜索命令

    3. 文件搜索命令 3.1 文件搜索:find (1)find命令 命令名称 find 命令所在路径 /bin/find 执行权限 所有用户 语法 find [搜索范围] [-选项] [匹配条件] - ...

  3. git教程链接

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

  4. .Net开源微型ORM框架测评

    什么是ORM? 对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间 ...

  5. mysql的基本命令行操作

    mysql>CREATE DATABASE imooc; //创建数据库 mysql> USE imooc ;//选择数据库 mysql> SELECT DATABASE();//查 ...

  6. jsp利用application统计在线人数的方法

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  7. 使用canvas绘制一片星空

    效果图 五角星计算方式 代码 <body style="margin:0px;padding:0px;width:100%;height:100%;overflow:hidden;&q ...

  8. Java语法

    java语法: 一个java程序可以说是一系列对象的集合,而这些对象都要通过调用彼此的方法来协同工作. 对象: 对象是一个实例,例如:一只猫,它是一个对象,有状态和行为.它的状态状态有:颜色,名字,品 ...

  9. 选择CRM

    第一:可扩展和定制 选择CRM系统一定要注意系统扩展性,要用发展的眼光去审视公司的CRM需求,所以CRM系统必须具有一定的扩展性,从而满足不断变化的公司需求.而那些看起来功能和强大不能扩展看起来貌似也 ...

  10. 【bzoj1227】 SDOI2009—虔诚的墓主人

    http://www.lydsy.com/JudgeOnline/problem.php?id=1227 (题目链接) 题意 一个n*m的公墓,一个点上要么是墓地,要么是常青树,给出一个数K,并规定每 ...