了解过PHP内核的同学都知道,PHP的一次请求的生命周期

1.启动Apache后,PHP解释程序也随之启动。PHP调用各个扩展的MINIT方法,从而使这些扩展切换到可用状态

2.当一个页面请求发生时,SAPI层将控制权交给PHP层。于是PHP设置了用于回复本次请求所需的环境变量。同时,它还建立一个变量表,用来存放执行过程 中产生的变量名和值。PHP调用各个模块的RINIT方法,即“请求初始化”。RINIT方法可以看作是一个准备过程, 在程序执行之间就会自动启动

3.如同PHP启动一样,PHP的关闭也分两步。一旦页面执行完毕(无论是执行到了文件末尾还是用exit或die函数中止),PHP就会启动清理程序。它会按顺序调用各个模块的RSHUTDOWN方法。 RSHUTDOWN用以清除程序运行时产生的符号表,也就是对每个变量调用unset函数。

4.最后,所有的请求都已处理完毕,SAPI也准备关闭了,PHP开始执行第二步:PHP调用每个扩展的MSHUTDOWN方法,这是各个模块最后一次释放内存的机会

以上是运行在Apache服务中,而Nginx+FastCgi似乎不是这样,这一点我会后期深究,今天主要探讨日志功能,便也后期学习


首先我们按照我的这篇博文(在Linux下编写php扩展)生成一个扩展

然后我们在myext.c文件中添加一个日志函数,然后分别在

PHP_MINIT_FUNCTION,PHP_MSHUTDOWN_FUNCTION,PHP_RINIT_FUNCTION,PHP_RSHUTDOWN_FUNCTION四个函数中添加调用日志的函数

然后编译扩展,重新服务,允许等操作,看看是否有日志

下面我给出一个完整的文件

 /*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2016 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: |
+----------------------------------------------------------------------+
*/ /* $Id$ */ #ifdef HAVE_CONFIG_H
#include "config.h"
#endif #include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "php_myext.h" /* If you declare any globals in php_myext.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(myext)
*/ /* True global resources - no need for thread safety here */
static int le_myext;
void save_log();
/* {{{ PHP_INI
*/
/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("myext.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_myext_globals, myext_globals)
STD_PHP_INI_ENTRY("myext.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_myext_globals, myext_globals)
PHP_INI_END()
*/
/* }}} */ /* Remove the following function when you have successfully modified config.m4
so that your module can be compiled into PHP, it exists only for testing
purposes. */ /* Every user-visible function in PHP should document itself in the source */
/* {{{ proto string confirm_myext_compiled(string arg)
Return a string to confirm that the module is compiled in */
PHP_FUNCTION(confirm_myext_compiled)
{
char *arg = NULL;
int arg_len, len;
char *strg; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
} len = spprintf(&strg, , "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "myext", arg);
RETURN_STRINGL(strg, len, );
} void save_log(char *str)
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime ); char buf[];
sprintf(buf, "%s", asctime (timeinfo)); FILE *fp = fopen("/Users/zongshuai/log/c.log", "a+");
////这里写一个绝对路径,请改成一下,大家还得注意权限问题,如果发现打印不出内容,检查一下权限
if (fp==) {
printf("can't open file\n");
return;
} strcat(str,"\r\n"); fseek(fp, ,SEEK_END);
fwrite(buf, strlen(buf) - , , fp);
fwrite(" ", , , fp);
fwrite(str, strlen(str) * sizeof(char), , fp);
fclose(fp);
return;
} PHP_FUNCTION(sum_two_num)
{
long x,y,z; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &x,&y) == FAILURE) {
RETURN_FALSE;
} char str[] = "EXECED MYFUNCTION";
save_log(str); z = x * y; RETURN_LONG(z);
}
/* }}} */
/* The previous line is meant for vim and emacs, so it can correctly fold and
unfold functions in source code. See the corresponding marks just before
function definition, where the functions purpose is also documented. Please
follow this convention for the convenience of others editing your code.
*/ /* {{{ php_myext_init_globals
*/
/* Uncomment this function if you have INI entries
static void php_myext_init_globals(zend_myext_globals *myext_globals)
{
myext_globals->global_value = 0;
myext_globals->global_string = NULL;
}
*/
/* }}} */ /* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(myext)
{
/* If you have INI entries, uncomment these lines
REGISTER_INI_ENTRIES();
*/
char str[] = "EXECED PHP_MINIT_FUNCTION";
save_log(str);
return SUCCESS;
}
/* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(myext)
{
/* uncomment this line if you have INI entries
UNREGISTER_INI_ENTRIES();
*/
char str[] = "EXECED PHP_MSHUTDOWN_FUNCTION";
save_log(str);
return SUCCESS;
}
/* }}} */ /* Remove if there's nothing to do at request start */
/* {{{ PHP_RINIT_FUNCTION
*/
PHP_RINIT_FUNCTION(myext)
{
char str[] = "EXECED PHP_RINIT_FUNCTION";
save_log(str);
return SUCCESS;
}
/* }}} */ /* Remove if there's nothing to do at request end */
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
PHP_RSHUTDOWN_FUNCTION(myext)
{
char str[] = "EXECED PHP_RSHUTDOWN_FUNCTION";
save_log(str);
return SUCCESS;
}
/* }}} */ /* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(myext)
{
php_info_print_table_start();
php_info_print_table_header(, "myext support", "enabled");
php_info_print_table_end(); /* Remove comments if you have entries in php.ini
DISPLAY_INI_ENTRIES();
*/
}
/* }}} */ /* {{{ myext_functions[]
*
* Every user visible function must have an entry in myext_functions[].
*/
const zend_function_entry myext_functions[] = {
PHP_FE(confirm_myext_compiled, NULL) /* For testing, remove later. */
PHP_FE(sum_two_num, NULL)
PHP_FE_END /* Must be the last line in myext_functions[] */
};
/* }}} */ /* {{{ myext_module_entry
*/
zend_module_entry myext_module_entry = {
STANDARD_MODULE_HEADER,
"myext",
myext_functions,
PHP_MINIT(myext),
PHP_MSHUTDOWN(myext),
PHP_RINIT(myext), /* Replace with NULL if there's nothing to do at request start */
PHP_RSHUTDOWN(myext), /* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(myext),
PHP_myext_VERSION,
STANDARD_MODULE_PROPERTIES
};
/* }}} */ #ifdef COMPILE_DL_myext
ZEND_GET_MODULE(myext)
#endif /*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/

使用日志记录功能查看PHP扩展的执行过程的更多相关文章

  1. HAproxy增加日志记录功能和自定义日志输出内容、格式

    http://blog.51cto.com/eric1/1854574 一.增加haproxy日志记录功能   1.1 由于数据分析的需要,我们必须打开haproxy日志,记录相关信息. 在配置前,我 ...

  2. 如何自行给指定的SAP OData服务添加自定义日志记录功能

    有的时候,SAP标准的OData实现或者相关的工具没有提供我们想记录的日志功能,此时可以利用SAP系统强大的扩展特性,进行自定义日志功能的二次开发. 以SAP CRM Fiori应用"My ...

  3. iptables log日志记录功能扩展应用:iptables自动配置临时访问策略,任意公网登录服务器

    一.修改日志记录: 1. 修改配置文件: vi /etc/rsyslog.conf 添加以下内容 #iptables log kern.=notice /var/log/iptables.log 2. ...

  4. 个人理解---在开发中何时加入日志记录功能[java]

    是这样的:俩个月前做的一个小功能,今天经理突然问我这个'清除复投记录'功能是不是我做的,我说是,很久以前了.他说昨天一个客户找过来了,后台把人家的复投记录清除掉了,不知道何时清除的,我记得当时做的时候 ...

  5. 【TP3.2】:日志记录和查看

    1.TP3.2手册日志类链接:http://document.thinkphp.cn/manual_3_2.html#log 2.日志默认路径:/Application/Runtime/Logs 3. ...

  6. tp5下通过composer实现日志记录功能

    tp5实现日志记录 1.安装 psr/log composer require psr/log 它的作用就是提供一套接口,实现正常的日志功能! 我们可以来细细的分析一下,LoggerInterface ...

  7. 在SpringBoot中用SpringAOP实现日志记录功能

    背景: 我需要在一个SpringBoot的项目中的每个controller加入一个日志记录,记录关于请求的一些信息. 代码类似于: logger.info(request.getRequestUrl( ...

  8. springcloud zuulfilter 实现get,post请求日志记录功能

    import com.alibaba.fastjson.JSONObject; import com.idoipo.infras.gateway.open.model.InvokeLogModel; ...

  9. php之框架增加日志记录功能类

    <?php /* 思路:给定文件,写入读取(fopen ,fwrite……) 如果大于1M 则重写备份 传给一个内容, 判断大小,如果大于1M,备份 小于则写入 */ class Log{ // ...

随机推荐

  1. node.js---package.json文件

    描述包的文件是package.json文件. 一个这样的文件,里面的信息还是挺大的.我们可以放弃手动建立.为了练手我们有命令行来建一个这样的包; 完成name,varsion....license项的 ...

  2. java中使用数组和链表简单实现SJBMap

    import java.util.LinkedList; public class SJBMap { private Object[] elementData; private int size; p ...

  3. 斗地主 (NOIP2015 Day1 T3)

    斗地主 张牌,因为它可以连在K后, 总体思路为 先出炸弹和四带二 再出三带一 再把对牌和单牌出完 记录并更新Answer,后枚举顺子,并继续向下搜索. 注意:弄明白题意,题目描述不太清楚....另外, ...

  4. Java中 +=是什么意思 什么情况下用

    x+=1与x=x+1一样的效果执行一次x=x+1,就等于给x重新赋了值,这个值就是x+1例如:int x=1;x+=1;最后x的值是2x+=1一般在循环下使用,能发挥它的最大的作用.例如:while( ...

  5. Design Pattern——开放封闭原则

    两个特征: 1.对于扩展是开放的 2.对于更改是封闭的 意思就是说:程序在设计的时候,时刻要考虑,尽量让这个类是足够好,写好了就不要去修改了,如果有新的需求来,我们就增加一个类来解决问题,而不要更改原 ...

  6. linux共享文件夹

    mnt中没有 hgfs,重新安装vm tools后问题解决

  7. C#中Invoke的用法

    在用.NET Framework框架的WinForm构建GUI程序界面时,如果要在控件的事件响应函数中改变控件的状态,例如:某个按钮上的文本原先叫"打开",单击之后按钮上的文本显示 ...

  8. 浏览器 CSS 兼容写法的测试总结

    做前端最讨厌的就是 IE6,7,8,虽然被淘汰的浏览器,但是在中国用户仍然很多,不可能像国外网站一样直接就不管它了,这样会流失很多流量啊. 现在有了IE9,IE10还好些,几乎和 Chrome,Fir ...

  9. noip2015Day2T1-跳石头

    题目描述 Description 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有N ...

  10. [妙味JS基础]第十一课:字符串、查找高亮显示

    知识点总结 字符串方法 var str = '2014年新春快乐哈' * length 字符串长度 str.length =>10 ------------------------------- ...