2012-03-20 3 views
1

기사를 저장하는 mysql 데이터베이스가 있다고 상상해보십시오.html로 PHP 코드 사용하기 ... PHP에서

<h1>I'm just foo</h1> 
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p> 
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</p> 

...

을 그리고는 mysql_query를 사용하여 그 결과를 통해 실행하는 표시 :

HTML

그래서 같이 저장된다.

그러나 여기에 문지르 기가 있습니다. 예를 들어, 언제나 사전 정의 된 함수를 사용하여 HTML에지도를 삽입하는 것이 좋습니다. 어떻게 사용자 입력, html로? 내부 PHP-태그와 PHP를 태그로 렌더링 할과

<?php insertMap() ?> 

: 난 안 잘 만 입력 할 수 있습니다.

나는 그것을 다르게 취급하는 다른 CMS를 보아 왔습니다. 예를 들어 {{{insertMap}}}을 사용하여 함수를 호출합니다. 그렇다면 코드를 실행하고 {{{}}}을 찾고이를 함수로 실행하는 방법은 무엇입니까?

Google과 나는 eval()이 솔루션의 일부라고 느끼지만 (보안 위험이 있긴하지만), 모든 제안, 포인터 등을 환영합니다!

답변

2

기본적으로 저장된 내용 내에서 찾기 및 바꾸기를 수행하여 해당 자리 표시 자 (형식은 자유롭게 결정할 수있는 형식)와 일치시키고 사용자가 파생 된 표현식을 평가 한 결과로 대체합니다. eval을 사용하는 것은 반드시 필요한 것은 아니며, eval의 안전한 하위 집합 만 지원하는 자신의 평가판과 유사한 코드를 매우 쉽게 옮길 수 있습니다.

자리 표시 자 템플릿으로 {{{xxx}}}을 선택한다고 가정 해 보겠습니다. 일치 시키려면 가장 쉬운 방법은 regular expressions에서 preg_match까지 또는 같은 가족에 속한 다른 함수를 사용하는 것입니다. 우리가 교체하기를 원하기 때문에 대체품이 동적으로 생성되기를 원한다면 preg_replace_callback으로 갈 것입니다.

대체 할 패턴은 중괄호 사이의 하나 이상의 문자 및 밑줄 시퀀스와 일치하는 '/{{{([a-zA-Z_]+)}}}/'입니다. 괄호 안에는 정규 표현식에 특정한 문법이 있으며 나는 그것을 사용하여 중괄호에 귀찮게하지 않고 나중에 (템플릿의 이름) 부분을 쉽게 참조 할 수 있습니다.

콜백 패턴 주어진 대체 컨텐츠를 생성하는 기능이 될 것입니다 :

이 기능은 템플릿 이름 ( {{{xxx}}}의 예 xxx)를 타고 함수가 있는지 확인하기 위해 설계되었습니다
function produce_replacement($match) { 
    // $match[1] means "the part of the template inside the braces"; 
    // read up on the documentation of preg_replace_callback for more. 
    $producerName = 'evaluate_'.strtolower($match[1]); 
    return function_exists($producerName) ? $producerName() : null; 
} 

evaluate_xxx이 존재합니다. 함수가 호출되면 함수를 호출하고 결과를 반환합니다. 그렇지 않은 경우 null을 반환합니다. 어떤 경우이든 결과는 원본 텍스트의 서식 파일로 대체됩니다.

중요 : 구현에 보안을 제공하는 디자인 결정입니다! 사용자가 텍스트 내에서 원하는 "템플릿"을 사용할 수 있도록했지만 템플릿은 evaluate_xxx 또는 그와 비슷한 함수 내에 해당 코드가있는 경우 코드가 실행됩니다. 이러한 함수의 존재 유무가 제어라는 것을 감안할 때, 사용자는 해당 태그가 실제로 수행 할 수있는 범위 내에서 제한됩니다.

그래서 당신은 지금 가질 수 있습니다

$text = "Hello there {{{name}}}!"; 
$pattern = '/{{{([a-zA-Z_]+)}}}/'; 

$text = preg_replace_callback($pattern, 'produce_replacement', $text); 
echo $text; 

function evaluate_name() { 
    return "Joe"; 
} 

See it in action합니다.

+0

와우, 훌륭합니다! 고맙습니다. 백만 분, 빨리 구현하려고합니다. – ThomasH

+0

다시 귀찮게해서 죄송합니다. :) 내 요구에 맞는 솔루션을 더 많이 또는 덜 채택했습니다. 실행중인 함수에 변수를 전달하는 것이 어려웠습니다. .. 내가 머리를 감쌀 수없는 것은 아마도 매우 간단 할 것이다. 나는 {{{showMap}}}, {{{showRating}}}, {{{subItems}}} 같은 페이지에. 세 가지 다른 호출이 있으면 첫 번째 호출 만 실행되지만 세 번 표시됩니다. 올바른 방향으로 나를 알려주는 조언이 있습니까? 감사 :) – ThomasH

1

많은 템플릿 엔진이 있는데, eval()을 사용하지 않고이 작업을 수행 할 수 있습니다. 고급 파싱 클래스. 기능 목록 등을 미리 정의하고 사용하십시오. 또는 템플릿 엔진 만 사용하십시오.

+0

실제로 5 줄의 코드로이 작업을 수행 할 수 있습니다. 템플릿 엔진, 파싱 클래스 등이 필요 없습니다. – Jon

+0

의견에 감사드립니다. 템플릿 엔진에서 읽을 것입니다. – ThomasH

+0

@ 존 예. 그렇지만 한 가지 기능에 대해서만 대답을 쓸 수 있습니다. – safarov