2010-04-13 3 views
7

나는 국제 수학 그룹을 지원하기 위해 고안된 포럼을 운영합니다. 나는 최근에 국제 문자에 대한 더 나은 지원을 위해 유니 코드로 전환했습니다. 이 전환을 디버깅 할 때 모든 유니 코드 문자가 유효한 XHTML로 간주되는 것은 아니며 관련 웹 사이트는 http://www.w3.org/TR/unicode-xml/ 인 것으로 나타났습니다. 게시물을 브라우저에 표시하기 전에 포럼 소프트웨어가 수행하는 단계 중 하나는 XHTML 확인/sanitisation 단계입니다. 그 단계에서 XHTML이 좋아하지 않는 유니 코드 문자를 제거해야한다는 것은 합당한 생각입니다.PHP를 사용하여 XHTML이 유효하지 않은 유니 코드 문자를 제거하는 가장 좋은 방법은 무엇입니까?

그래서 제 질문은 : 표준 (또는 최고) PHP에서이 일의 방법은

있습니까?

이 (포럼은 그런데, PHP로 작성된 것입니다.)

내가 그 또한 최선의 경우 안전 장치가 (간단한 str_replace 될 것이라고 생각, 내가 확인하기 위해 추가 작업을 수행 할 필요합니까 그것은 유니 코드와 제대로 작동합니까?) 그러나 그게 XHTML DTD (위 참조 된 W3 페이지)를 통해 검색 부분에 나열 할 문자를 파악해야하므로이 경우 가장 좋은 방법은 이미 누군가가 그것을 훔칠 수 있도록, 잘못, 복사, 그것을 했나요?

(유효 HTML 만 유효 XHTML은 또한, 문제의 원인이 된 캐릭터가합니다 (W3 페이지에 따라 '폼 피드'U + 000C,,)이었다입니다!)

답변

2

난 당신이 phpedit.net에 원하는 것을 할 수있는 기능을 발견했다.

나는, 아카이브에 대한 기능을 게시합니다은 PHPEdit.net에 LTP 크레딧 :

/** 
* Removes invalid XML 
* 
* @access public 
* @param string $value 
* @return string 
*/ 
function stripInvalidXml($value) 
{ 
    $ret = ""; 
    $current; 
    if (empty($value)) 
    { 
     return $ret; 
    } 

    $length = strlen($value); 
    for ($i=0; $i < $length; $i++) 
    { 
     $current = ord($value{$i}); 
     if (($current == 0x9) || 
      ($current == 0xA) || 
      ($current == 0xD) || 
      (($current >= 0x20) && ($current <= 0xD7FF)) || 
      (($current >= 0xE000) && ($current <= 0xFFFD)) || 
      (($current >= 0x10000) && ($current <= 0x10FFFF))) 
     { 
      $ret .= chr($current); 
     } 
     else 
     { 
      $ret .= " "; 
     } 
    } 
    return $ret; 
} 
+0

나는 이것이 preg_replace 메소드 (특히 http://php.net/manual/en/regexp.reference.unicode.php에서 속도에 대한 설명이 주어짐), 내 자신의 화이트리스트를 찾아야하는 것과 같은 단점이 있습니다! (게으른 것에 대한 위의 주석을보십시오!) –

+0

자신의 화이트리스트를 알아낼 필요가 없습니다. 문자는 ASCII 코드를 기반으로 허용되며 함수에 의해 지정된 범위를 벗어나면 공백으로 바뀝니다. 나는 이것이 당신이 필요로 할 모든 것이라고 확신합니다, 화이트리스트는 이미 기능에 있습니다. – Bas

+0

확실히 그 기능에는 * 하나 * 화이트리스트가 있지만 올바른 화이트리스트라는 것을 어떻게 알 수 있습니까? 예를 들어 HTML에서는 0xC가 허용되지만 XHTML에서는 허용되지 않습니다. 허용 목록에서 작업하는 경우 DTD에서 어떻게 든 생성되어야합니다. –

1

은 가정 귀하의 의견은 당신이 UTF8입니다

preg_replace('~[\x{17A3}-\x{17D3}]~u', '', $input); 

또 다른, 더 나은처럼 뭔가 유니 코드 범위를 제거 할 수 있습니다, 접근 방식은 기본적으로 당신이보고 싶어에만 허용 된 사이트 목록 문자에 의해 모든 것을 제거하는 것입니다. 유니 코드 속성 (\ p)은이 작업에 매우 유용합니다. 예를 들어, (유니 코드) 문자와 숫자를 제외한 모든 것을 제거합니다

preg_replace('~[^\p{L}\p{N}]~u', '', $input) 
+0

다음 방법 중 하나를 사용하여 내 문제는 내가 화이트리스트 또는 블랙리스트를 추출하기 위해 DTD를 통과해야한다는 것입니다 일치하는. 나는 누군가 누군가 나를 위해 그것을 벌써 가지고 있기를 바라고 있었다! 유효한 XHTML 인 모든 문자에 대해 '\ p {XHTML}'이 있다고 가정하지 않습니다. (저는 수학자이고 우리는 근본적으로 게으른 무리입니다 - 다른 누군가가 이미 문제를 해결했다면 우리는 다시하지 않는 것을 원치 않습니다!) –

+0

나는 그런 해결책을 알고 있지 않지만 당신은 빠르고 쉬운 방법을 찾고 있습니다. 문자 - 숫자 - 구두점을 제외한 모든 것을 단순히 숫자로 변환 할 수 있습니다. – user187291

+0

"everything-except"를 엔티티로 변환하면 작동하지 않습니다. 엔티티로 인코딩 된 경우에도 유효한 세트 외부의 문자를 보내면 브라우저가 불평 할 것입니다. (아마 내가 XHTML + MathML을 제공하고 있다는 것을 분명히해야합니다. 그래서 * 100 % 유효한 * - 브라우저에 의존하여 유효하지 않은 엔터티를 무시할 수는 없습니다.) –

관련 문제