当前位置: 首页 > news >正文

wordpress 行业模版/seo推广外包企业

wordpress 行业模版,seo推广外包企业,施工企业在施工过程中发现设计文件和图纸有差错的,ei网站怎么兼做0x00问题背景群友抛出一个题,空数组array()与0 比较大小的结果如何?另一个群友也借机抛出了另一个问题var_dump(null 0);var_dump(null array());var_dump(0 array());答案也有些匪夷所思,第一个问题的结果是,array()>0 第二…

0x00问题背景

群友抛出一个题,空数组array()与0 比较大小的结果如何?

另一个群友也借机抛出了另一个问题

var_dump(null == 0);

var_dump(null == array());

var_dump(0 == array());

答案也有些匪夷所思,第一个问题的结果是,array()>0 第二个问题结果是 true,true,false

0x01问题讨论

实验得到结果后的第一反应就是查文档,于是在php的官方文档中找到如下内容:

becfacf970434823a7c2a87b6f1a6397.png

0d843d17b14b9bf5bc30bf5f823b0b4a.png

在这里赞一下PHP的文档,描述很详实,demo也有代表性,相信这在语言的推广上起了不少作用。

问题似乎是解决了,但我还是不满足,颇有点知其然不知其所以然的感觉,于是产生了后面的内容。

0x02进一步探究

第一个比较初级的想法就是查看opcode,在这里简单提一下opcode。引用官方文档的一段话:

When parsing PHP files, Zend Engine 2 generates a series of operation codes,

commonly known as "opcodes", representing the function of the code.

大意是:Zend引擎在解析PHP文件时,会产生一组操作码,被称作“opcode”,用来表示代码中函数。我觉得描述基本如此,这里就不展开讲了。

于是做了如下实验:

1.建立test文件,内容如下:

var_dump(array() == 0);

2.通过vld扩展查看此段代码的opcode

eed5d32db98508860efb92a2318b4001.png

从上图的opcode中可以看出除了变量初始化,以及变量返回,并没有对变量比较做更多的展开。关键的内容其实在3行 IS_EQUAL 操作符具体的执行过程当中。于是在PHP文档中找到如下内容PHP: IS_EQUAL - Manual,只有一个关于该操作符的demo,并没有更多的内容。于是只剩下最后一招。

0x03查看源码

开源就是有这个好处,遇到问题逼不得已还可以看源码,一切也算是掌握之中(从这点上讲IOS的开发者很多情况就只能摸索了)。PHP的源码项目下载可以参见PHP: Git Access,本文参考PHP5.6的源码

在Zend引擎中,每个opcode根据操作参数的不同(上图中每一行的OP1、OP2)有25个opcode_handler,具体的配置可以参见zend_vm_excute.h 文件

static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)

{

static const int zend_vm_decode[] = {

_UNUSED_CODE, /* 0              */

_CONST_CODE,  /* 1 = IS_CONST   */

_TMP_CODE,    /* 2 = IS_TMP_VAR */

_UNUSED_CODE, /* 3              */

_VAR_CODE,    /* 4 = IS_VAR     */

_UNUSED_CODE, /* 5              */

_UNUSED_CODE, /* 6              */

_UNUSED_CODE, /* 7              */

_UNUSED_CODE, /* 8 = IS_UNUSED  */

_UNUSED_CODE, /* 9              */

_UNUSED_CODE, /* 10             */

_UNUSED_CODE, /* 11             */

_UNUSED_CODE, /* 12             */

_UNUSED_CODE, /* 13             */

_UNUSED_CODE, /* 14             */

_UNUSED_CODE, /* 15             */

_CV_CODE      /* 16 = IS_CV     */

};

return zend_opcode_handlers[opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type]];

}

该方法是在Zend引擎中根据opcode 与参数获取opcode handler的方法,可以看到是从zend_opcode_handlers数组中获取的。该数组在 zend_init_opcodes_handlers 方法中初始化,由于数组定义太长(4000行+)就不一一列出了,截取与IS_EQUAL 相关部分:

2812b6264b9587e679478e1c182662d2.png

具体定位的过程,就将opcode的值带入公式

opcode * 25 + zend_vm_decode[op->op1_type] * 5 + zend_vm_decode[op->op2_type]

当中,opcode的值可以在PHP文档中查到,IS_EQUAL的opcode值为17,当然也可以看到handlers的命名还是很规范的,根据opcode的名字也可以搜索到。根据0x02中的opcode可以看出,两个参数的类型分别为IS_TMP_VAR,IS_CONST。定位到函数ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER中

static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)

{

USE_OPLINE

zend_free_op free_op1;

zval *op1, *op2, *result;

op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);

op2 = EX_CONSTANT(opline->op2);

do {

int result;

if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {

if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {

result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));

} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {

result = ((double)Z_LVAL_P(op1) == Z_DVAL_P(op2));

} else {

break;

}

} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {

if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {

result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));

} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {

result = (Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));

} else {

break;

}

} else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {

if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {

if (Z_STR_P(op1) == Z_STR_P(op2)) {

result = 1;

} else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {

if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {

result = 0;

} else {

result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);

}

} else {

result = (zendi_smart_strcmp(op1, op2) == 0);

}

zval_ptr_dtor_nogc(free_op1);

} else {

break;

}

} else {

break;

}

ZEND_VM_SMART_BRANCH(result, 0);

ZVAL_BOOL(EX_VAR(opline->result.var), result);

ZEND_VM_NEXT_OPCODE();

} while (0);

SAVE_OPLINE();

if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {

op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);

}

if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {

op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);

}

result = EX_VAR(opline->result.var);

compare_function(result, op1, op2);

ZVAL_BOOL(result, Z_LVAL_P(result) == 0);

zval_ptr_dtor_nogc(free_op1);

ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();

}

而根据具体的变量类型,IS_ARRAY、IS_LONG走了一圈的if else 发现最后又进了compare_function,该函数的实现可以在zend_operator.c文件中找到。由于函数比较长,switch了各种情况,就不把函数贴上来了。不过在这个函数里最初的两个问题得到了我最满意的解释。

0x04总结

google是解决问题的利器,好的文档也非常管用。偶尔自己深究一下,乐在其中。

http://www.jmfq.cn/news/4949587.html

相关文章:

  • html门户网站模板/现在最火的发帖平台
  • 计算机网站建设实训报告/富阳网站seo价格
  • 辽宁省住房城乡建设委网站/免费接单平台
  • 网站建设开发合同/网站名称查询
  • 快站网如何开始建站/百度提问首页
  • 合肥做网站联系方式/重庆森林经典台词梁朝伟
  • 成品源码网站永久地址入口进入/河北百度推广客服电话
  • 电子商务网站建设第三章答案/产品推广计划方案模板
  • 搭建wordpress步骤/无线网络优化
  • 京东的网站是哪家公司做的/周口网络推广哪家好
  • 贵阳网站建设电话/seo专员是什么意思
  • 什么网站可以兼职做鸭子/全球搜索网站排名
  • 网站建设管理招聘/怎么在百度上面打广告
  • 网站内的地图导航怎么做/河南最近的热搜事件
  • 做网站还有流量么/宁波网站关键词优化公司
  • 女装网站模板/新东方在线教育平台官网
  • 易企cms/论坛优化seo
  • 游戏软件开发需要多少钱/成都高新seo
  • 专做排版网站/电商网址
  • 牛商网做网站/长沙大型网站建设公司
  • 做网站后台应该谁来做/巨量算数
  • 聊城网站开发/百度站长平台提交网站
  • wordpress查看error/市场seo是什么意思
  • 服务器如何限制每个网站的空间使用大小/磁力宅在线搜种子
  • 多语种网站怎么做搜索引擎排名/免费seo关键词优化服务
  • 做家政有专门的网站吗/新闻头条最新消息摘抄
  • 网站开发项目答辩主持词/优化设计三要素
  • 网站支付页面怎么做/百度账号客服24小时人工电话
  • 可视化建站源码/整站seo优化哪家好
  • 建筑公司网站源码/北京优化网站公司