PHP nasıl recursive fonksiyon çağrıları yapar?

4 Cevap php

(Diğerleri) PHP yolunda çalışma dışarı, ilk derin işlevini yürütecek. Örneğin,

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

Ben bir şablon çözümleyici için yukarıdaki örneğe çok benzer bir şey yapıyorum. Bu etiketleri arar

{@tag_name}

ve adı bir değişken ile değiştirir $tag_name. Bir örnek daha:

$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.';

Bunu nasıl yapıyor hakkında gidebilirsiniz? Bu mantıklı mı? Eğer değilse, ben daha iyi açıklayan deneyebilirsiniz.

4 Cevap

Ben örnek yuvalama arkasında bir amaç göstermek değil gibi ben, sizin örnekte iç içe geçme anlamak emin değilim. Sizin örnek giriş çok kolay olabilir

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

Ve str_replace dizileri kullanarak çok basit ve hızlı bir şekilde bu ele olacaktır.

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

echo str_replace(array_keys($aVars), array_values($aVars), $sString);

Bize verir

Bu benim test hello world dizedir.

Ben olurdu ne kadar yararlı anlamak emin değilim ama şimdi, bu bir özyinelemeli fonksiyon, çok zor değildir. Burada çalışan bir örnektir:

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;
}

Bu print_r maçı onun adım aracılığıyla işlevi takip böylece neye size gösterecektir. Şimdi bunu deneyelim ...

$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 />';

İlk Sonucu:

Bu benim test hello world dizedir.

Şimdi dize iki deneyelim

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

İkinci Sonuç:

Bu benim test {@ aworld} dizedir.

Bu çok iyi aradığınız şey olabilir. Açıkçası özyinelemeli bu iş için bir aworld değişkeni gerekir ...

$aVars = array('a' => '', 'b' => '2', 'a2' => 'hello world');

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

Ve sonuç.

Bu benim test hello world dizedir.

Ve sadece özyineleme ile bazı eğlence için ...

$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 />';

Bu benim test hello world dizedir.

Değil bu sizin için soruyorsun ne ise emin ...

Bu önemsiz bir görev değildir. El dizesini ayrıştırmak ve kendi mantıksal değiştirmelerin yapmak gerekir. Sizin için yapacak hiçbir sihirli bir işlev ya da işlevselliği var.

Benim kendi motor şablonu bu konuda yaptığı (ve daha fazla) ve sadece çekirdek (hiçbir şablon makrolar) + LOC 600 ağırlığında

Bir yığın kullanın - üstüne array_push, açılan her bir eleman koymak ve değerlendirmek array_pop birinci kapatma işaretine üstteki.

B @ belirteç @ bir belirteç iç içe olacağını neden verilen örnekte, en azından ben anlamıyorum. Birbiriniz için herhangi bir ihtiyaç görünmüyor. Eğer Perl böyle bir şey yapmaya çalışıyorsun?

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

print $$a;

çıktı "Merhaba Dünya" olacağını