前回はPHP Extension を作って関数をフックしてみた

今回は HTTP リクエストを受け取った際に特定のパラメータを取得しロギングする PHP Extensions を作成してみる。

リクエストを受けつけるごとに読み込む必要があるため、 PHP_RINIT_FUNCTION として定義する。

zend_module_entry logging_module_entry = {
  STANDARD_MODULE_HEADER,
  "logging",                      /* Extension name */
  logging_functions,              /* zend_function_entry */
  NULL,                           /* PHP_MINIT - Module initialization */
  NULL,                           /* PHP_MSHUTDOWN - Module shutdown */
  PHP_RINIT(logging),             /* PHP_RINIT - Request initialization */
  NULL,                           /* PHP_RSHUTDOWN - Request shutdown */
  PHP_MINFO(logging),             /* PHP_MINFO - Module info */
  PHP_LOGGING_VERSION,            /* Version */
  STANDARD_MODULE_PROPERTIES
};

PHP_RINIT_FUNCTION では POST リクエストのときに param という名前のパラメータを取得し php_printf でその値を表示する。

PHP_RINIT_FUNCTION(logging)
{
#if defined(ZTS) && defined(COMPILE_DL_LOGGING)
  ZEND_TSRMLS_CACHE_UPDATE();
#endif
  zval *param;
  zval *post_array;
  HashTable *post_hash;
  post_array = &PG(http_globals)[TRACK_VARS_POST]; //Array
  post_hash = HASH_OF(post_array);

  param = zend_hash_str_find(post_hash, "param", strlen("param"));
  if (param != 0) {
    php_printf("param is %s\n", Z_STRVAL_P(param));
  }

  return SUCCESS;
}

ちなみに、GETCookie の値を取得したい場合は次のようにする。

/* GET */
zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_GET]);
ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_GET], &array);

/* Cookie */
zval_ptr_dtor_nogc(&PG(http_globals)[TRACK_VARS_COOKIE]);
ZVAL_COPY_VALUE(&PG(http_globals)[TRACK_VARS_COOKIE], &array);

これをビルドして動作させると、期待通りの動きをしてくれる。

$ php -S localhost:8000
$ curl localhost:8000 --data "param=test"
param is test
php  c