我在查看
我尝试使用 Vulcan Logic Dumper 扩展来检查底层发生了什么。
我试着使用以下代码进行测试:
php-src/Zend/zend_API.c
时,并没有找到 PHP 中 strlen()
函数的源代码,在整个代码库中搜索并不会有太多帮助,因为 libc strlen
函数随处可见。谷歌搜索也没什么用。我尝试使用 Vulcan Logic Dumper 扩展来检查底层发生了什么。
我试着使用以下代码进行测试:
<?php
strlen("foo"); strpos("foo", "f");
我得到的内容如下:
查找入口点 从位置0开始分析分支 发现1个跳转。 (Code = 62) 位置1 = -2 文件名:/ tmp / test.php 函数名称:(null) 操作数数量:7 编译变量:none 行#*EIO op fetch ext return operands -------------------------------------------------- ----------------------------------- 3 0 E > ECHO 3 4 1 INIT_FCALL 'strpos' 2 SEND_VAL 'foo' 3 SEND_VAL 'o' 4 DO_ICALL $0 5 ECHO $0 6 > RETURN 1
注意strpos()
显示为函数调用,但strlen()
没有显示。所以我在 PHP 7.4 上进行了一个实验,并得到了一些有趣的结果。
代码
<?php
$str = "foo";
echo strlen($str);
echo strpos($str, "o");
Vulcan的输出
查找入口点 从位置0开始分析分支 发现1个跳转 (代码=62),位置1=-2 文件名:/tmp/test2.php 函数名:(null) 操作数:9 已编译变量:!0=$str 行号 #* E I O 操作 获取 扩展 返回值 操作数 ------------------------------------------------------------------------------------- 2 0 E > ASSIGN !0, 'foo' 4 1 STRLEN ~2 !0 2 ECHO ~2 5 3 INIT_FCALL 'strpos' 4 SEND_VAR !0 5 SEND_VAL 'o' 6 DO_ICALL $3 7 ECHO $3 8 > RETURN 1
注意,STRLEN
突然出现在操作列表中,但是奇怪的是,strpos()
函数以 INIT_FCALL
的形式出现。看起来 strlen()
和其他函数不同。我尝试查阅官方手册以更好地了解操作码的工作方式,但没能找到太有用的信息。
有没有人可以解释一下为什么 strlen()
表现得如此不同于其他函数,并可能指向它的源代码?也许我找不到它的原因与它如此特殊有关?我不确定。
strlen()
在内部映射到ZSTR_LEN()
,2)您可以在此处找到PHPstrpos()
的源代码:https://github.com/php/php-src/blob/master/ext/standard/string.c - FoggyDay