PHP는 재귀 함수 호출을 어떻게 수행합니까?
문제
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.';
이 작업을 어떻게 수행할 수 있나요?이게 말이 돼?그렇지 않다면 더 잘 설명하려고 노력할 수 있습니다.
해결책
예제에서는 중첩의 목적을 보여주지 않기 때문에 예제의 중첩을 이해하지 못합니다.귀하의 예제 입력은 매우 쉽게 될 수 있습니다
'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 문자열입니다.
이제 문자열 2를 시도해 보겠습니다.
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 문자열입니다.
이것이 당신이 요구하는 것인지 확실하지 않습니다 ...
다른 팁
이것은 사소한 일이 아닙니다. 문자열을 수동으로 구문 분석하고 자신의 논리적 대체를 수행해야합니다. 당신을 위해 이것을 할 마법 기능이나 기능은 없습니다.
내 자신의 템플릿 엔진은 그것 (그리고 그 이상)에 대해 수행하고 코어 (템플릿 매크로 없음) 만 600+ LOC에 있습니다.
스택을 사용하십시오 - 위에 올려 놓으십시오 array_push
각각이 열린 요소를 최상으로 평가했습니다 array_pop
첫 번째 마크에서.
적어도 주어진 예에서는 @B 토큰이 @A 토큰에 중첩되는 이유를 이해하지 못합니다. 두 사람은 서로가 필요하지 않은 것 같습니다. Perl에서 이런 일을하려고합니까?
$a = "b";
$b = "Hello World!";
print $$a;
그런 다음 출력은 "Hello World"입니다.