PHP中的strlen()函数的源代码在哪里? [英] Where is the source code for strlen() function in PHP?

查看:244
本文介绍了PHP中的strlen()函数的源代码在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在浏览 php-src/Zend/zend_API.c 并且在任何地方都找不到PHP中strlen()函数的源代码.遍历代码库并没有真正的帮助,因为到处都有libc strlen.谷歌搜索也无济于事.

I was looking through php-src/Zend/zend_API.c and couldn't find the source code for the strlen() function in PHP anywhere. Grepping through the code base didn't really help as it's littered with libc strlen everywhere. Googling doesn't much help either.

我尝试使用 Vulcan Logic Dumper 扩展程序来检查引擎盖下的情况.

I tried using the Vulcan Logic Dumper extension to inspect what's going on under the hood.

我尝试了以下代码作为测试:

I tried the following code as a test:

<?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                                         $0      
         5        ECHO                                                     $0
         6      > RETURN                                                   1

请注意strpos()如何显示为函数调用,但不显示为strlen().因此,我尝试了此操作(顺便说一句,在PHP 7.4上为 ),并得到了一些有趣的东西.

Notice how strpos() shows up as a function call, but not strlen(). So I tried this (this on PHP 7.4, by the way) as an experiment and got something interesting.

<?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                                         $3      
         7        ECHO                                                     $3
         8      > RETURN                                                   1

注意突然之间STRLEN如何出现在操作列表中,但是奇怪的是strpos()却显示为INIT_FCALL.似乎strlen()与其他函数有所不同.我尝试查看手册以更好地了解操作码的工作原理,但是由于那里没有太多有用的信息.

Notice how all of a sudden STRLEN shows up in the op list, but strangely enough strpos() shows up as INIT_FCALL. Seems like something's different about strlen() than other functions. I tried looking through the manual to better understand how the opcodes work, but hit a dead end as not much useful information is there.

任何人都可以解释为什么strlen()的行为似乎与其他函数有很大不同,并且也许为此指出了我的源代码吗?也许我似乎找不到其来源的原因可能与它如此特别的原因有关?我不确定.

Can anyone explain why strlen() seems to behave so different than other functions and perhaps point me to the source code for it? Perhaps the reason I cannot seem to find its source might have something to do with why it's so special? I'm not sure.

推荐答案

strlen()实际上是PHP 7中的操作码,因此其行为不像典型的函数.其源代码位于 php-src/Zend/zend_string.h 在第53行(截至撰写本文时),该行定义为宏.

strlen() is actually an opcode in PHP 7 and thus doesn't behave like a typical function. Its source code is located in php-src/Zend/zend_string.h on line 53 (as of the time of this writing), which is defined as a Macro.

#define ZSTR_LEN(zstr)  (zstr)->len

基本上,这只是阅读

It's basically just reading the len member of the _zend_string struct, which stores the length of the string as a member.

如果您查看 git-blame ,您会发现该特定宏是在2015年PHP 7发布时添加的.

If you look at the git-blame you'll see that particular macro was added around the time of PHP 7's release in 2015.

这里是提交: https://github.com/php/php-src/提交/4bd22cf1c1d6a262fe2f026e082f2565433c53df

这是我的git日志所说的:

Here's what my git log says:


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()从一个函数变成了一个操作码,或者它始终是一个操作码.

So it looks like at some point around PHP 7's release some improvements were made to the API. It's unclear if this means strlen() went from being a function to being an opcode, or if it was always an opcode.

不过,我确实看到了 interned string 东西可能会如何影响实验中Vulcan的输出.如果您使用插入字符串,则出于某种原因,PHP似乎在执行程序中采用了某种快捷方式.我不清楚具体如何,但是是的,它的行为似乎与典型函数有所不同.

I do see, though, how the interned string stuff might effect the output of Vulcan in your experiment. If you use an interned string PHP seems to take some kind of shortcut in the executor for some reason. I'm unclear as to how, exactly, but yes it does appear to behave somewhat differently from a typical function.

这篇关于PHP中的strlen()函数的源代码在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆