最初の便利な PHP 拡張機能
PHP 開発者にとって、学ぶべきことはたくさんあると思いますが、もちろん PHP 拡張機能の開発も必須のスキルです。ここで偉大な鳥の兄弟 (Laruence) に敬意を表したいと思います~
今日開発される最初の機能拡張の主な機能は、ログを記録するときにログの前に日付部分を生成することです。 🎜 >
<code>#即使当前的时间,年-月-日 时:分:秒 时间戳.微妙数 [2015-05-19 20:39:32 1432039172.968199]</code>php 拡張関数 prelude最初に「スケルトン」を生成します:
<code>1. 进入php源码src/ext目录下面2. 运行./ext_skel --extname=mytest3. 进入src/ext/mytest/目录4. 在编写扩展的时候要先修改下config.me文件的10-12行,去掉前面的dnl注释,这个网上一搜一大把。</code>ヘッダー ファイル php_mttest に書き込む php 拡張関数の名前を宣言します.h
<code>PHP_FUNCTION(get_log_title);#PHP_FUNCTION是PHP内核中声明的一个宏#define PHP_FUNCTION ZEND_FUNCTION //在文件src/main/php.h : 347行#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name)) //文件src/Zend/zend_API.h : 68行#define ZEND_FN(name) zif_##name //文件src/Zend/zend_API.h : 65行#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS) //文件src/Zend/zend_API.h : 67行#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC //src/Zend/zend.h : 290行</code>上記の宣言関数マクロを展開すると、次のようになります。
<code>void zif_get_log_title( int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC)</code>mytest.c の zend_function_entry 宣言に get_log_title 関数の宣言を追加します
<code>const zend_function_entry logs_functions[] = { PHP_FE(confirm_logs_compiled, NULL) /* For testing, remove later. */ PHP_FE(get_log_title, NULL) PHP_FE_END /* Must be the last line in logs_functions[] */};#编写函数PHP_FUNCTION(get_log_title){ struct timeval tv; time_t rawtime; struct tm *timeinfo; char *formatinfo; time(&rawtime); timeinfo = localtime(&rawtime); gettimeofday(&tv, NULL); spprintf(&formatinfo, 0, "[%4d-%02d-%02d %d:%d:%d %d.%d]", 1900 + timeinfo->tm_year, 1 + timeinfo->tm_mon, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, tv.tv_sec, tv.tv_usec); RETURN_STRING(formatinfo, 1);}</code>こちらも参照 RETURN_STRING マクロを見てください
<code>#define RETURN_STRING(s, duplicate) { RETVAL_STRING(s, duplicate); return; } //文件src/Zend/zend_API.h : 635行#define RETVAL_STRING(s, duplicate) ZVAL_STRING(return_value, s, duplicate) //文件src/Zend/zend_API.h : 623行#define ZVAL_STRING(z, s, duplicate) do { \ //文件src/Zend/zend_API.h : 577-583行,这个的作用其实是给一个string类型zval变量赋值 const char *__s=(s); \ zval *__z = (z); \ Z_STRLEN_P(__z) = strlen(__s); \ //设置zval字符串长度 Z_STRVAL_P(__z) = (duplicate?estrndup(__s, Z_STRLEN_P(__z)):(char*)__s);\ //设置zval字符串的值 Z_TYPE_P(__z) = IS_STRING; \ //设置zval字符串的类型为字符串} while (0)</code>したがって、RETURN_STRING(formatinfo, 1) は次のように展開されます:
<code>do { const char *__s=(formatinfo); zval *__z = (return_value); //这里面的return_value估计是内核定义的,类似 zval *return_value; (*__z).value.str.len = strlrn(__s); //等价于__z->value.str.len (*__z).value.str.val = (1?estrndup(__s, (*__z).value.str.len):(char*)__s); (*__z).type = 6; }</code>コンパイル テスト
<code>编译的时候需要安装好的php,比如我的php安装在/usr/local/php/目录下面cd mytest; //今日刚才编写的函数扩展目录/usr/local/php/bin/phpize //运行phpize,生成configure文件./configure --with-php-config=/usr/local/php/bin/php-config //configure,后面的--with-php-config会生成so文件到安装好的扩展目录,当然也可以不用加,声称之后手动copy过去make //有错误的话修正make install //运行之后会提示类似下面的内容#Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20100525/#修改配置文件php.ini添加extension = mytest.so#测试php -r 'var_dump(log_get_title());'</code>以下の内容が出力された場合、成功おめでとうございます
<code>[[email protected] logs]# php -r 'var_dump(get_log_title());' && datestring(39) "[2015-05-19 22:52:29 1432047149.755613]"2015年 05月 19日 星期二 22:52:29 CST</code>
5/19/2015 10:54:38 PMこの記事の著作権は以下に属します著者からは ifforever (luluyrt@163.com) に送信され、著作権は著者から許可されていません。記事を転載した後は、著者と元のテキストのリンクを目立つように表示する必要があることに同意します。そうでない場合、私は法的責任を追及する権利を留保します。