PHP中strlen()函数的源代码在哪里?
Where is the source code for strlen() function in PHP?
我正在查看 php-src/Zend/zend_API.c
,但在任何地方都找不到 PHP 中 strlen()
函数的 源代码 。遍历代码库并没有真正帮助,因为它到处都是 libc strlen
。谷歌搜索也没有太大帮助。
我尝试使用 Vulcan Logic Dumper 扩展来检查幕后发生的事情。
我尝试了以下代码作为测试:
<?php
strlen("foo"); strpos("foo", "f");
这是我得到的:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /tmp/test.php
function name: (null)
number of ops: 7
compiled vars: none
line #* E I O 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 [=23=]
5 ECHO [=23=]
6 > RETURN 1
请注意 strpos()
如何显示为函数调用,而不是 strlen()
。所以我尝试了这个(this on PHP 7.4,顺便说一句)作为一个实验,得到了一些有趣的东西。
代码
<?php
$str = "foo";
echo strlen($str);
echo strpos($str, "o");
Vulcan 的输出
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename: /tmp/test2.php
function name: (null)
number of ops: 9
compiled vars: !0 = $str
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
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
7 ECHO
8 > RETURN 1
请注意 STRLEN
是如何突然出现在操作列表中的,但奇怪的是 strpos()
却显示为 INIT_FCALL
。 strlen()
似乎与其他函数有所不同。我尝试了 looking through the manual to better understand how the opcodes 工作,但由于没有太多有用的信息而陷入了死胡同。
任何人都可以解释为什么 strlen()
的行为似乎与其他函数如此不同,也许可以向我指出它的源代码?也许我无法找到它的来源的原因可能与它如此特别的原因有关?我不确定。
strlen()
实际上是 PHP 7 中的一个操作码,因此表现得不像一个典型的函数。它的源代码位于php-src/Zend/zend_string.h
第53行(截至撰写本文时),它被定义为一个宏。
#define ZSTR_LEN(zstr) (zstr)->len
基本上就是读取_zend_string
struct的len
成员,将字符串的长度存储为成员。
如果您查看 git-blame,您会发现该特定宏是在 2015 年 PHP 7 发布时添加的。
这是提交:https://github.com/php/php-src/commit/4bd22cf1c1d6a262fe2f026e082f2565433c53df
这是我的 git 日志中的内容:
commit 4bd22cf1c1d6a262fe2f026e082f2565433c53df
Author: Dmitry Stogov
Date: Mon Jun 29 16:44:54 2015 +0300
Improved zend_string API (Francois Laupretre)
Squashed commit of the following:
commit d96eab8d79b75ac83d49d49ae4665f948d15a804
Author: Francois Laupretre
Date: Fri Jun 26 01:23:31 2015 +0200
Use the new 'ZSTR' macros in the rest of the code.
Does not change anything to the generated code (thanks to compat macros) but cleaner.
commit b3526439104ac7a89a8e0c79dbebf33b22bd01b8
Author: Francois Laupretre
Date: Thu Jun 25 13:45:06 2015 +0200
Improve zend_string API
Add missing methods
所以看起来 PHP 7 发布前后的某个时候对 API 进行了一些改进。目前还不清楚这是否意味着 strlen()
从一个函数变成了一个操作码,或者它是否一直是一个操作码。
不过,我确实看到 interned string 内容可能会如何影响 Vulcan 在您的实验中的输出。如果您使用实习字符串 PHP 似乎出于某种原因在执行程序中采用了某种快捷方式。我不清楚具体如何,但是是的,它的行为似乎与典型函数有些不同。
我正在查看 php-src/Zend/zend_API.c
,但在任何地方都找不到 PHP 中 strlen()
函数的 源代码 。遍历代码库并没有真正帮助,因为它到处都是 libc strlen
。谷歌搜索也没有太大帮助。
我尝试使用 Vulcan Logic Dumper 扩展来检查幕后发生的事情。
我尝试了以下代码作为测试:
<?php
strlen("foo"); strpos("foo", "f");
这是我得到的:
Finding entry points Branch analysis from position: 0 1 jumps found. (Code = 62) Position 1 = -2 filename: /tmp/test.php function name: (null) number of ops: 7 compiled vars: none line #* E I O 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 [=23=] 5 ECHO [=23=] 6 > RETURN 1
请注意 strpos()
如何显示为函数调用,而不是 strlen()
。所以我尝试了这个(this on PHP 7.4,顺便说一句)作为一个实验,得到了一些有趣的东西。
代码
<?php
$str = "foo";
echo strlen($str);
echo strpos($str, "o");
Vulcan 的输出
Finding entry points Branch analysis from position: 0 1 jumps found. (Code = 62) Position 1 = -2 filename: /tmp/test2.php function name: (null) number of ops: 9 compiled vars: !0 = $str line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 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 7 ECHO 8 > RETURN 1
请注意 STRLEN
是如何突然出现在操作列表中的,但奇怪的是 strpos()
却显示为 INIT_FCALL
。 strlen()
似乎与其他函数有所不同。我尝试了 looking through the manual to better understand how the opcodes 工作,但由于没有太多有用的信息而陷入了死胡同。
任何人都可以解释为什么 strlen()
的行为似乎与其他函数如此不同,也许可以向我指出它的源代码?也许我无法找到它的来源的原因可能与它如此特别的原因有关?我不确定。
strlen()
实际上是 PHP 7 中的一个操作码,因此表现得不像一个典型的函数。它的源代码位于php-src/Zend/zend_string.h
第53行(截至撰写本文时),它被定义为一个宏。
#define ZSTR_LEN(zstr) (zstr)->len
基本上就是读取_zend_string
struct的len
成员,将字符串的长度存储为成员。
如果您查看 git-blame,您会发现该特定宏是在 2015 年 PHP 7 发布时添加的。
这是提交:https://github.com/php/php-src/commit/4bd22cf1c1d6a262fe2f026e082f2565433c53df
这是我的 git 日志中的内容:
commit 4bd22cf1c1d6a262fe2f026e082f2565433c53df Author: Dmitry Stogov Date: Mon Jun 29 16:44:54 2015 +0300 Improved zend_string API (Francois Laupretre) Squashed commit of the following: commit d96eab8d79b75ac83d49d49ae4665f948d15a804 Author: Francois Laupretre Date: Fri Jun 26 01:23:31 2015 +0200 Use the new 'ZSTR' macros in the rest of the code. Does not change anything to the generated code (thanks to compat macros) but cleaner. commit b3526439104ac7a89a8e0c79dbebf33b22bd01b8 Author: Francois Laupretre Date: Thu Jun 25 13:45:06 2015 +0200 Improve zend_string API Add missing methods
所以看起来 PHP 7 发布前后的某个时候对 API 进行了一些改进。目前还不清楚这是否意味着 strlen()
从一个函数变成了一个操作码,或者它是否一直是一个操作码。
不过,我确实看到 interned string 内容可能会如何影响 Vulcan 在您的实验中的输出。如果您使用实习字符串 PHP 似乎出于某种原因在执行程序中采用了某种快捷方式。我不清楚具体如何,但是是的,它的行为似乎与典型函数有些不同。