[ PHP 内核与扩展开发系列] PHP 启动与终止那点事:MINFO 与 phpinfo() 函数

如果你并不打算做出一个只有你自己使用的扩展,那么你可能需要告诉用户一些关于你的扩展的信息。比如:其环境和特定版本的可用功能、版本信息、作者信息,以便在发生问题的时候可以寻求帮助,甚至可以加上一个 LOGO 等等。

如果你仔细看过 phpinfo() 或者 php -i 的输出,相信你已经注意到,所有这些信息会组合成一个格式良好的、易于解析输出的数据块。你的扩展可以轻松地通过模块信息函数 MINFO 来添加这些块,看个例子:

PHP_MINFO_FUNCTION(sample4) {
    php_info_print_table_start();
    php_info_print_table_row(2, "Sample4 Module", "enabled");
    php_info_print_table_row(2, "version", PHP_SAMPLE4_EXTVER);
    php_info_print_table_end();
}

通过使用这些封装的函数,模块的信息将被自动包裹在 HTML 标签中,从一个网络服务器 SAPI (如CGI、IIS、APACHE 等等)输出,或格式化通过 CLI 使用时,输出明文和换行符。

下面我们来介绍一下 php_info_*() 系列的函数:

char *php_info_html_esc(char *str TSRMLS_DC)

这个函数是 php_escape_html_entities() 的一个封装,htmlentites() 函数的底层实现。该函数返回的字符串通过 emalloc() 创建,在使用后必须使用 efree() 函数释放掉。

void php_info_print_table_start(void)
void php_info_print_table_end(void)

输出开/关表格式所需的标签。HTML 输出时与 CLI 输出一样,表现为一个简单的换行。

void php_info_print_table_header(int cols, ...)
void php_info_print_table_colspan_header(int cols, char *header)

输出表头行。第一个函数在可变参数列表中的 char * 元素外面的每一列都会输出一对 th 标签,第二个函数会在指定列数外面输出一对 th 标签。

void php_info_print_table_row(int cols, ...)
void php_info_print_table_row_ex(int cols, char *class, ...)

第一个函数在可变参数列表中的 char * 元素外面的每一行都会输出一对 td 标签,第二个函数会在指定列数外面输出一对 td 标签;前者会自动添加一个 "class=v" 属性到 td 标签,后者允许传递一个自定义类名。当不在 HTML 中输出时,两个函数没有任何差别。

void php_info_print_hr(void)

这个函数将在 HTML 中输出一个 br 标签,或者一个表示行开始和结束的水平线。

我们常用的 PHPWRITE()php_printf() 函数可以在在 MINFO 函数中使用,你应该注意正确的信息输出取决于当前的 SAPI 判断是用纯文本还是 HTML 的方式输出。要做到这一点,只需要检查sapi_module 结构中的 phpinfo_as_text 属性,示例如下:

// 扩展配置信息
PHP_MINFO_FUNCTION(academy_sample_ini) {
    php_info_print_table_start();
    php_info_print_table_row(2, "Academy Module", "enabled");
    php_info_print_table_row(2, "version", PHP_ACADEMY_EXTVER);
    if (sapi_module.phpinfo_as_text) {
        /* No HTML for you */
        php_info_print_table_row(2, "By",
            "Laravel学院\nhttp://laravelacademy.org");
    } else {
        /* HTMLified version */
        php_printf("<tr>"
            "<td class=\"v\">By</td>"
            "<td class=\"v\">"
            "<a href=\"http://laravelacademy.org\""
            " alt=\"Laravel学院\">"
            "<img src=\"http://static.laravelacademy.org/wp-content/themes/wp-knowledge-base/logo.png\" />"
            "</a></td></tr>");
    }
    php_info_print_table_end();
}

注:使用 sapi_module 之前需要在头文件中引入 ZAPI.h#include "SAPI.h",否则在make 的时候会报错。

重新编译扩展,我们在浏览器中查看 phpinfo() 输出,会看到扩展的配置信息如下:

学院君 has written 716 articles

资深PHP工程师,Laravel学院院长

发表评论

标记为*的字段是必填项(邮箱地址不会被公开)

你可以使用这些HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>