2010-12-22 4 views
0

사이트 뉴스 XML 파일을 편집하기 위해 작은 PHP 스크립트를 작성했습니다. DOM을 사용하여 XML (로드, 쓰기, 편집)을 조작했습니다.PHP : 비 영어 문자를 XML 인코딩 문제로 작성

영어 문자를 쓸 때 잘 작동하지만 영어가 아닌 문자를 쓰면 PHP가 파일을로드 할 때 오류가 발생합니다.

비 영어 문자를 파일에 수동으로 입력하면 완벽하게로드되지만 완벽하지는 않지만 PHP에서 영어 이외의 문자를 쓰면 utf-8 인코딩을 지정했지만 인코딩이 잘못됩니다.

도움을 주시면 감사하겠습니다.

업데이트 : 유용한 답변과 함께 해결되었습니다 (아래 참조).

오류 :

경고 :있는 DOMDocument :: 부하() [domdocument.load] :: DOMDocument를 부하() [: 엔티티 타임즈하지 은 파일 경로에

경고 정의 domdocument.load] : 입력이 이 아니라 올바른 UTF-8 인코딩을 나타냅니다! 바이트 : 0x91 0x26 따라 0x74 0x69에서 파일 경로

다음

로드하고 파일을 저장 (자명)을 담당하는 기능은 다음과 같습니다 여기

function get_tags_from_xml(){ 
// Load news entries from XML file for display 
    $errors = Array(); 

    if(!$xml_file = load_news_file()){ 
    // Load file 
     // String indicates error presence 
     $errors = "file not found"; 
     return $errors; 
    } 
    $taglist = $xml_file->getElementsByTagName("text"); 
    return $taglist; 
} 
function set_news_lang(){ 
// Sets the news language 
    global $news_lang; 

    if($_POST["news-lang"]){ 
     $news_lang = htmlentities($_POST["news-lang"]); 
    } 
    elseif($_GET["news-lang"]){ 
     $news_lang = htmlentities($_GET["news-lang"]); 
    } 
    else{ 
     $news_lang = "he"; 
    } 
} 
function load_news_file(){ 
// Load XML news file for proccessing, depending on language 
    global $news_lang; 

    $doc = new DOMDocument('1.0','utf-8'); 
    // Create new XML document 
    $doc->load("news_{$news_lang}.xml"); 
    // Load news file by language 
    $doc->formatOutput = true; 
    // Nicely format the file 

    return $doc; 
} 
function save_news_file($doc){ 
// Save XML news file, depending on language 
    global $news_lang; 

    $doc->saveXML($doc->documentElement); 
    $doc->save("news_{$news_lang}.xml"); 
} 

XML로 작성하기위한 코드입니다 (뉴스 추가) :

<?php ob_start()?> 
<?php include("include/xml_functions.php")?> 
<?php include("../include/functions.php")?> 
<?php get_lang();?> 
<?php 
//TODO: ADD USER AUTHENTICATION! 
if(isset($_POST["news"]) && isset($_POST["news-lang"])){ 
    set_news_lang(); 

    $news = htmlentities($_POST["news"]); 

    $xml_doc = load_news_file(); 
    $news_list = $xml_doc->getElementsByTagName("text"); 
    // Get all existing news from file 

    $doc_root_element = $xml_doc->getElementsByTagName("news")->item(0); 
    // Get the root element of the new XML document 
    $new_news_entry = $xml_doc->createElement("text",$news); 
    // Create the submited news entry 

    $doc_root_element->appendChild($new_news_entry); 
    // Append submited news entry 
    $xml_doc->appendChild($doc_root_element); 

    save_news_file($xml_doc); 

    header("Location: /cpanel/index.php?lang={$lang}&news-lang={$news_lang}"); 
} 
else{ 
    header("Location: /cpanel/index.php?lang={$lang}&news-lang={$news_lang}"); 
} 
?> 
<?php ob_end_flush()?> 

업데이트 : 사용자가 제공 한 도움이 대답과의 해결 : 형식에 의해 제출 된 값은 영어가 아닌이며, 일부 HTML 엔티티를 포함, POST에서 htmlentities()을 사용했기 때문에 영어가 아닌 문자열을 읽을 수 없습니다. htmlentities()htmlspecialchars()으로 대체했으며 마술처럼 작동합니다.

결론 : htmlentities() 영어가 아닌 문자열을 망칠 수 있습니다.

+0

'htmlspecialchars()'와 조심하십시오 - 주체를 수정하는 것 외에도 비 유니 코드 문자 (즉, ASCII/1252 등가물)를 비트 주변에 넣을 수도 있습니다. 'str_replace()'는 보통 더 안전합니다 :) –

답변

2

문자 인코딩은 항상 번거롭습니다. 양식이 들어있는 페이지, $ dom에로드 한 XML 및 PHP 파일 자체가 utf-8로 인코딩되었는지 확인하십시오. 그렇지 않으면 모든 문자열이 표시되지 않으며 utf-8로 처리하면 작동하지 않습니다.

사용해보기 : 원본 뉴스 XML을 빈 페이지에 표시합니다. 그런 다음 브라우저에서 페이지 인코딩을 전환하여 어느 것이 올바르게 표시되는지 확인하십시오. 양식에서 입력을 검색 한 후 $ news에 대해이를 반복하십시오. 이것은 대개 인코딩이 잘못되는 위치에 대한 단서를 제공합니다.

+0

thanks! 나는 뉴스를 되풀이했고, 그것은 열렬한 gibrish에서 나왔다. 새 항목을 추가하는 과정은 HTML없이 PHP 만 분리 된 파일에서 실행됩니다. 내 생각 엔 그 파일에 인코딩을 어떻게 든 설정해야합니다. 또는 POST에서 잘못 될 수도 있습니다. – Dean

+0

OK 코드 내에서 $ news에 영어가 아닌 문자열 값을 할당하려고 시도했지만 POST를 통해 제대로 전송되지 않는다고 생각합니다. – Dean

+0

나는 그것을 해결했다! 질문을 읽고, 그것을 업데이트했습니다. – Dean

1

이 앱 떨어져 좀 더 당겨없이 정확한 문제를 진단하기 어렵다, 그러나 이것은 좋은 단서이다 :

경고 : DOMDocument를 :: 부하() [domdocument.load] : 엔티티 '배 '파일 경로에 정의되지 않았습니다.

XML은 일반적으로 &times;과 같은 HTML 엔티티를 좋아하지 않습니다.작동 보장 된 엔티티는 &lt;, &gt;, &amp;&quot;입니다.

대신 수치 엔티티를 사용하십시오. 따라서 ×의 경우 &#xD7; 등을 사용하십시오.

다음은 html_entities에 전화 후 추가 할 수있는 신속하고 더러운 트릭 :

foreach(array('quot'=>34,'amp'=>38,'lt'=>60,'gt'=>62,'OElig'=>338,'oelig'=>339, 
'Scaron'=>352,'scaron'=>353,'Yuml'=>376,'circ'=>710,'tilde'=>732,'ensp'=>8194, 
'emsp'=>8195,'thinsp'=>8201,'zwnj'=>8204,'zwj'=>8205,'lrm'=>8206,'rlm'=>8207, 
'ndash'=>8211,'mdash'=>8212,'lsquo'=>8216,'rsquo'=>8217,'sbquo'=>8218,'ldquo'=>8220, 
'rdquo'=>8221,'bdquo'=>8222,'dagger'=>8224,'Dagger'=>8225,'permil'=>8240,'lsaquo'=>8249, 
'rsaquo'=>8250,'euro'=>8364,'fnof'=>402,'Alpha'=>913,'Beta'=>914,'Gamma'=>915, 
'Delta'=>916,'Epsilon'=>917,'Zeta'=>918,'Eta'=>919,'Theta'=>920,'Iota'=>921, 
'Kappa'=>922,'Lambda'=>923,'Mu'=>924,'Nu'=>925,'Xi'=>926,'Omicron'=>927, 
'Pi'=>928,'Rho'=>929,'Sigma'=>931,'Tau'=>932,'Upsilon'=>933,'Phi'=>934, 
'Chi'=>935,'Psi'=>936,'Omega'=>937,'alpha'=>945,'beta'=>946,'gamma'=>947, 
'delta'=>948,'epsilon'=>949,'zeta'=>950,'eta'=>951,'theta'=>952,'iota'=>953, 
'kappa'=>954,'lambda'=>955,'mu'=>956,'nu'=>957,'xi'=>958,'omicron'=>959, 
'pi'=>960,'rho'=>961,'sigmaf'=>962,'sigma'=>963,'tau'=>964,'upsilon'=>965, 
'phi'=>966,'chi'=>967,'psi'=>968,'omega'=>969,'thetasym'=>977,'upsih'=>978, 
'piv'=>982,'bull'=>8226,'hellip'=>8230,'prime'=>8242,'Prime'=>8243,'oline'=>8254, 
'frasl'=>8260,'weierp'=>8472,'image'=>8465,'real'=>8476,'trade'=>8482,'alefsym'=>8501, 
'larr'=>8592,'uarr'=>8593,'rarr'=>8594,'darr'=>8595,'harr'=>8596,'crarr'=>8629, 
'lArr'=>8656,'uArr'=>8657,'rArr'=>8658,'dArr'=>8659,'hArr'=>8660,'forall'=>8704, 
'part'=>8706,'exist'=>8707,'empty'=>8709,'nabla'=>8711,'isin'=>8712,'notin'=>8713, 
'ni'=>8715,'prod'=>8719,'sum'=>8721,'minus'=>8722,'lowast'=>8727,'radic'=>8730, 
'prop'=>8733,'infin'=>8734,'ang'=>8736,'and'=>8743,'or'=>8744,'cap'=>8745, 
'cup'=>8746,'int'=>8747,'there4'=>8756,'sim'=>8764,'cong'=>8773,'asymp'=>8776, 
'ne'=>8800,'equiv'=>8801,'le'=>8804,'ge'=>8805,'sub'=>8834,'sup'=>8835, 
'nsub'=>8836,'sube'=>8838,'supe'=>8839,'oplus'=>8853,'otimes'=>8855,'perp'=>8869, 
'sdot'=>8901,'lceil'=>8968,'rceil'=>8969,'lfloor'=>8970,'rfloor'=>8971,'lang'=>9001, 
'rang'=>9002,'loz'=>9674,'spades'=>9824,'clubs'=>9827,'hearts'=>9829,'diams'=>9830, 
'nbsp'=>160,'iexcl'=>161,'cent'=>162,'pound'=>163,'curren'=>164,'yen'=>165, 
'brvbar'=>166,'sect'=>167,'uml'=>168,'copy'=>169,'ordf'=>170,'laquo'=>171, 
'not'=>172,'shy'=>173,'reg'=>174,'macr'=>175,'deg'=>176,'plusmn'=>177, 
'sup2'=>178,'sup3'=>179,'acute'=>180,'micro'=>181,'para'=>182,'middot'=>183, 
'cedil'=>184,'sup1'=>185,'ordm'=>186,'raquo'=>187,'frac14'=>188,'frac12'=>189, 
'frac34'=>190,'iquest'=>191,'Agrave'=>192,'Aacute'=>193,'Acirc'=>194,'Atilde'=>195, 
'Auml'=>196,'Aring'=>197,'AElig'=>198,'Ccedil'=>199,'Egrave'=>200,'Eacute'=>201, 
'Ecirc'=>202,'Euml'=>203,'Igrave'=>204,'Iacute'=>205,'Icirc'=>206,'Iuml'=>207, 
'ETH'=>208,'Ntilde'=>209,'Ograve'=>210,'Oacute'=>211,'Ocirc'=>212,'Otilde'=>213, 
'Ouml'=>214,'times'=>215,'Oslash'=>216,'Ugrave'=>217,'Uacute'=>218,'Ucirc'=>219, 
'Uuml'=>220,'Yacute'=>221,'THORN'=>222,'szlig'=>223,'agrave'=>224,'aacute'=>225, 
'acirc'=>226,'atilde'=>227,'auml'=>228,'aring'=>229,'aelig'=>230,'ccedil'=>231, 
'egrave'=>232,'eacute'=>233,'ecirc'=>234,'euml'=>235,'igrave'=>236,'iacute'=>237, 
'icirc'=>238,'iuml'=>239,'eth'=>240,'ntilde'=>241,'ograve'=>242,'oacute'=>243, 
'ocirc'=>244,'otilde'=>245,'ouml'=>246,'divide'=>247,'oslash'=>248,'ugrave'=>249, 
'uacute'=>250,'ucirc'=>251,'uuml'=>252,'yacute'=>253,'thorn'=>254,'yuml'=>255 
) as $alpha=>$num) 
$news=str_replace("&$alpha;", "&#$num;", $news); 

당신은 preg_replacearray_map와 애호가 일을 할 수 있지만, 이것은 당신이해야하는 데이터입니다.

성능이 문제가되는 경우 멋진 멀티 바이트 문자 검색을 수행하고 명명 된 엔티티 단계를 건너 뛸 수 있습니다. PHP 웹 사이트에는 많은 예제가 있습니다. 당신이 UTF8 인코딩 된 같은 XML 문서를 표시 한 경우

엄밀히 말하자면, 당신은 완전히 인코딩 엔티티를 떠나, 단지 네 가지 주요 사람을 인코딩 할 수 있습니다 :

$table = array('&' => '&amp;', '<' => '&lt;', '>' => '&gt;', '"' => '&quot;'); 
$news = str_replace(array_keys($table), array_values($table), $_POST["news"]); 

N을.

+0

팁 주셔서 감사. 여기에서 나의 문제는 텍스트를 쓰려고하는 동안 영어 이외의 문자가 처음부터 엔티티로 작성된다는 것입니다. – Dean

+0

내 대답의 데이터를 사용하여 이름이 지정된 엔티티를 수치 엔티티로 바꾸거나 UTF8로 인코딩 된 유니 코드를 사용하여 수학에 만족할 수 있습니다. 어떤 종류의 단체와 함께 일해야합니까? –

관련 문제