php扩展练习-入门

参考引文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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值