【问题标题】:How does PHP do recursive function calls?PHP如何进行递归函数调用?
【发布时间】:2010-09-20 01:52:07
【问题描述】:

PHP(以及其他)将首先执行最深的函数,然后逐步退出。例如,

$text = strtoupper(str_replace('_', ' ', file_get_contents('file.txt')));

我正在做与上面的模板解析器示例非常相似的事情。它寻找标签

{@tag_name}

并将其替换为名称为 $tag_name 的变量。再举一个例子:

$a = 'hello';
$b = ' world';
INPUT = 'This is my test {@a{@b}} string.';
OUTPUT (step 1) = 'This is my test {@a} world string.';
OUTPUT output = 'This is my test hello world string.';

我该怎么做呢?这有意义吗?如果没有,我可以尝试解释得更好。

【问题讨论】:

  • 为什么第 1 步的输出不是:'This is my test {@a world} string.';

标签: php string recursion


【解决方案1】:

这不是一项简单的任务。您需要手动解析字符串并进行自己的逻辑替换。没有任何神奇的功能或功能可以为您做到这一点。

我自己的模板引擎可以做到这一点(以及更多),只有核心(无模板宏)的重量为 600+ LOC

【讨论】:

    【解决方案2】:

    至少在给定的示例中,我不明白为什么 @b 令牌会嵌套在 @a 令牌中。两个人似乎没有什么需要。你想在 Perl 中做这样的事情吗?

    $a = "b";
    $b = "Hello World!";
    
    print $$a;
    

    输出将是“Hello World”

    【讨论】:

      【解决方案3】:

      使用堆栈 - 将每个打开的元素放在顶部 array_push 并在第一个结束标记处评估最顶部的 array_pop。

      【讨论】:

        【解决方案4】:

        我不确定我是否理解您示例中的嵌套,因为该示例没有说明嵌套背后的目的。您的示例输入很容易

        'This is my test {@a} {@b} string.'
        

        在 str_replace 中使用数组会非常简单快速地处理这个问题。

        $aVars = array('{@a}' => 'hello', '{@b}' => 'world');
        $sString = 'This is my test {@a} {@b} string.';
        
        echo str_replace(array_keys($aVars), array_values($aVars), $sString);
        

        这给了我们

        这是我的测试 hello world 字符串。

        现在,对此的递归函数并不太难,尽管我不确定我是否理解它会有多大用处。这是一个工作示例:

        function template($sText, $aVars) {
            if (preg_match_all('/({@([^{}]+)})/',
                               $sText, $aMatches, PREG_SET_ORDER)) {
                foreach($aMatches as $aMatch) {
                    echo '<pre>' . print_r($aMatches, 1) . '</pre>';
        
                    if (array_key_exists($aMatch[2], $aVars)) {
                        // replace the guy inside
                        $sText = str_replace($aMatch[1], $aVars[$aMatch[2]], $sText);
        
                        // now run through the text again since we have new variables
                        $sText = template($sText, $aVars);
                    }
                }
            }
        
            return $sText;
        }
        

        print_r 将向您显示匹配项的外观,以便您可以按照函数的步骤进行操作。现在让我们试一试...

        $aVars = array('a' => 'hello', 'b' => 'world');
        $sStringOne = 'This is my test {@a} {@b} string.';
        $sStringTwo = 'This is my test {@a{@b}} string.';
        
        echo template($sStringOne, $aVars) . '<br />';
        

        第一个结果:

        这是我的测试 hello world 字符串。

        现在让我们试试第二个字符串

        echo template($sStringTwo, $aVars) . '<br />';
        

        第二个结果:

        这是我的测试 {@aworld} 字符串。

        这很可能就是您正在寻找的。显然,您需要一个 aworld 变量才能使其递归工作...

        $aVars = array('a' => '', 'b' => '2', 'a2' => 'hello world');
        
        echo template($sStringTwo, $aVars) . '<br />';
        

        还有我们的结果。

        这是我的测试 hello world 字符串。

        只是为了递归的一些乐趣......

        $aVars = array('a3' => 'hello world', 'b2' => '3', 'c1' => '2', 'd' => '1');
        $sStringTre = 'This is my test {@a{@b{@c{@d}}}} string.';
        
        echo template($sStringTre, $aVars) . '<br />';
        

        这是我的测试 hello world 字符串。

        不确定这是否是您要求的...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-05-26
          • 2023-04-06
          相关资源
          最近更新 更多