템플릿 문법 오류와 해결법¶
PCRE Recursion Limit 오류¶
증상¶
- 복잡한 조건문이나 반복문 사용 시 백지 화면 표시
- 특히 cond 속성이 많이 중첩된 경우 발생
원인¶
PHP의 PCRE(Perl Compatible Regular Expression) 재귀 제한 설정 때문에 발생합니다.
해결 방법¶
- index.php 파일 수정
define('__XE__', TRUE);
// PCRE 재귀 제한 늘리기
@ini_set('pcre.recursion_limit', 500000);
@ini_set('pcre.backtrack_limit', 500000);
- .htaccess 파일에 추가 (Apache 서버)
php_value pcre.recursion_limit 500000
php_value pcre.backtrack_limit 500000
- 설정 확인 방법
<?php
// test.php 파일 생성
ini_set('pcre.recursion_limit', 500000);
echo ini_get('pcre.recursion_limit');
// 500000이 출력되면 정상
근본적인 해결책¶
템플릿 파일을 분리하여 복잡도를 줄입니다:
<!-- 나쁜 예: 하나의 파일에 모든 조건문 -->
<div cond="$a">
<div cond="$b">
<div cond="$c">
<!-- 깊은 중첩 -->
</div>
</div>
</div>
<!-- 좋은 예: 파일 분리 -->
<include target="_section.html" cond="$a" />
일반적인 문법 오류¶
1. 따옴표 오류¶
<!-- 잘못된 예 -->
<div class="wrapper" cond="$type == "main""> <!-- 따옴표 충돌 -->
<!-- 올바른 예 -->
<div class="wrapper" cond="$type == 'main'">
<!-- 또는 -->
<div class="wrapper" cond="$type == "main"">
2. 변수 범위 오류¶
<!-- 잘못된 예 -->
<ul>
<li loop="$list => $item">
{$item->title}
</li>
</ul>
<p>{$item->title}</p> <!-- $item은 loop 밖에서 사용 불가 -->
<!-- 올바른 예 -->
{@ $last_item = null}
<ul>
<li loop="$list => $item">
{$item->title}
{@ $last_item = $item}
</li>
</ul>
<p cond="$last_item">{$last_item->title}</p>
3. 중첩 루프 변수 충돌¶
<!-- 잘못된 예 -->
<div loop="$categories => $item">
<ul loop="$item->children => $item"> <!-- $item 변수 충돌 -->
<li>{$item->title}</li>
</ul>
</div>
<!-- 올바른 예 -->
<div loop="$categories => $category">
<ul loop="$category->children => $child">
<li>{$child->title}</li>
</ul>
</div>
4. 조건문 문법 오류¶
<!-- 잘못된 예 -->
<div cond="$logged_info->is_admin = 'Y'"> <!-- = 대신 == 사용 -->
<!-- 올바른 예 -->
<div cond="$logged_info->is_admin == 'Y'">
<!-- 잘못된 예 -->
<div cond="$count => 0"> <!-- => 대신 >= 사용 -->
<!-- 올바른 예 -->
<div cond="$count >= 0">
5. include 경로 오류¶
<!-- 잘못된 예 -->
<include target="/skins/board/normal/header.html" /> <!-- 절대 경로 -->
<!-- 올바른 예 -->
<include target="header.html" /> <!-- 상대 경로 -->
<!-- 또는 -->
<include target="./header.html" />
성능 관련 문제¶
1. 반복문 내 무거운 연산¶
<!-- 나쁜 예 -->
<li loop="$documents => $doc">
{@ $member_info = getMemberInfo($doc->member_srl)} <!-- 매번 쿼리 -->
{$member_info->nick_name}
</li>
<!-- 좋은 예 -->
{@
// 미리 회원 정보 로드
$member_srls = array();
foreach($documents as $doc) {
$member_srls[] = $doc->member_srl;
}
$member_infos = getMembersInfo($member_srls);
}
<li loop="$documents => $doc">
{$member_infos[$doc->member_srl]->nick_name}
</li>
2. 불필요한 조건 검사¶
<!-- 나쁜 예 -->
<block cond="$document_list">
<block cond="count($document_list) > 0">
<block cond="is_array($document_list)">
<!-- 중복 검사 -->
</block>
</block>
</block>
<!-- 좋은 예 -->
<block cond="$document_list && count($document_list) > 0">
<!-- 내용 -->
</block>
호환성 문제¶
1. PHP 버전별 차이¶
<!-- PHP 5.x와 7.x 호환 -->
{@
// 배열 선언
$arr = array(); // PHP 5.x 호환
// $arr = []; // PHP 5.4+
}
<!-- 널 병합 연산자 -->
<!-- PHP 7.0+ -->
{$title ?? '기본 제목'}
<!-- PHP 5.x 호환 -->
{isset($title) ? $title : '기본 제목'}
2. XE/Rhymix 버전 차이¶
<!-- Rhymix 전용 기능 사용 시 -->
<!--@if(defined('RX_VERSION'))-->
<!-- Rhymix 전용 코드 -->
{rx_lang('message')}
<!--@else-->
<!-- XE 호환 코드 -->
{$lang->message}
<!--@endif-->
디버깅 팁¶
1. 변수 확인¶
<!-- 개발 중 변수 내용 확인 -->
<!--@if(__DEBUG__)-->
<div style="background: #ffc; padding: 10px; margin: 10px 0;">
<h4>디버그 정보</h4>
<pre>{print_r($variable, true)}</pre>
</div>
<!--@endif-->
2. 에러 추적¶
{@
// 에러 로깅
if(!$document) {
debugPrint('Document not found: ' . $document_srl);
}
}
3. 템플릿 컴파일 캐시 확인¶
템플릿 수정 후 변경사항이 반영되지 않을 때:
files/cache/template_compiled/
디렉토리 삭제- 브라우저 캐시 삭제
- 디버그 모드 활성화
권장사항¶
- 템플릿 검증: 수정 후 항상 문법 오류 확인
- 점진적 개발: 복잡한 템플릿은 단계별로 개발
- 코드 분리: 로직은 PHP, 표현은 템플릿으로 분리
- 주석 활용: 복잡한 조건문에는 주석 추가
- 테스트: 다양한 조건에서 템플릿 동작 확인