php扩展练习-入门

来源:互联网 发布:知乎 汽车金融风控 编辑:程序博客网 时间:2024/06/09 14:47
参考引文http://www.cunmou.com/phpbook/index.md,今天来做一个php源码的改动验证。

引文2.1中提及:

这样我们便可以猜测一下php内核是如何实现gettype这个函数了,代码如下:

    //开始定义php语言中的函数gettype    PHP_FUNCTION(gettype)    {        //这个arg间接指向就是我们传给gettype函数的参数。是一个zval**结构        //所以我们要对他使用__PP后缀的宏。        zval **arg;        //这个if的操作主要是让arg指向参数~        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {            return;        }        //调用Z_TYPE_PP宏来获取arg指向zval的类型。        //然后是一个switch结构,RETVAL_STRING宏代表这gettype函数返回的字符串类型的值        switch (Z_TYPE_PP(arg)) {            case IS_NULL:                RETVAL_STRING("NULL", 1);                break;            case IS_BOOL:                RETVAL_STRING("boolean", 1);                break;            case IS_LONG:                RETVAL_STRING("integer", 1);                break;            case IS_DOUBLE:                RETVAL_STRING("double", 1);                break;            case IS_STRING:                RETVAL_STRING("string", 1);                break;            case IS_ARRAY:                RETVAL_STRING("array", 1);                break;            case IS_OBJECT:                RETVAL_STRING("object", 1);                break;            case IS_RESOURCE:                {                    char *type_name;                    type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);                    if (type_name) {                        RETVAL_STRING("resource", 1);                        break;                    }                }            default:                RETVAL_STRING("unknown type", 1);        }    }

为了验证gettype函数的底层实现,找到文件/ext/standard/type.c把gettype实现函数替换下玩玩:

      PHP_FUNCTION(gettype)      {          zval **arg;          if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {              return;          }          switch (Z_TYPE_PP(arg)) {              case IS_NULL:                  RETVAL_STRING("Bingo NULL", 1);                  break;              case IS_BOOL:                  RETVAL_STRING("Bingo boolean", 1);                  break;              case IS_LONG:                  RETVAL_STRING("Bingo integer", 1);                  break;              case IS_DOUBLE:                  RETVAL_STRING("Bingo double", 1);                  break;              case IS_STRING:                  RETVAL_STRING("Bingo string", 1);                  break;              case IS_ARRAY:                  RETVAL_STRING("Bingo array", 1);                  break;              case IS_OBJECT:                  RETVAL_STRING("Bingo object", 1);              /*                 {                 char *result;                 int res_len;                 res_len = sizeof("object of type ")-1 + Z_OBJCE_P(arg)->name_length;                 spprintf(&result, 0, "object of type %s", Z_OBJCE_P(arg)->name);                 RETVAL_STRINGL(result, res_len, 0);                 }               */                  break;              case IS_RESOURCE:                  {                      const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);                      if (type_name) {                          RETVAL_STRING("resource", 1);                          break;                      }                  }              default:                  RETVAL_STRING("unknown type", 1);          }      }

按照引文4.3所述,下载php源码,配置,编译。这里–prefix填写编译后的目录路径前缀,譬如/home/users/yangding/php,最后执行make install安装,安装结果将放在/home/users/yangding/php目录下。
安装完成后,执行测试代码

    /home/users/yangding/php/bin/php -r '$test =1;print_r(gettype($test));'

得到运行结果

    Bingo integer
0 0