strip_tags htmlspecialchars_decode escape characters aacute php xml xml-serialization

escape - php htmlspecialchars_decode



PHP-¿Es htmlentities() suficiente para crear valores xml-safe? (5)

Entonces, su pregunta es "¿está garantizado que el resultado de htmlentities () será compatible con XML y UTF-8?" La respuesta es no, no lo es.

htmlspecialchars () debería ser suficiente para escapar de los caracteres especiales de XML, pero tendrá que desinfectar sus cadenas UTF-8 de cualquier manera. Incluso si construyes tu XML con, digamos, SimpleXML, deberás desinfectar las cadenas. No sé sobre otras librerías como XMLWriter o DOM, creo que es lo mismo.

Estoy construyendo un archivo XML desde cero y necesito saber si htmlentities () convierte cada carácter que potencialmente podría romper un archivo XML (y posiblemente datos UTF-8). Los valores serán de un feed de Twitter / Flickr, ¡así que necesito estar seguro!


La respuesta de Gordon es buena y explica los problemas de codificación XML, pero no muestra una función simple (o lo que hace la caja negra). La respuesta de Jon comienza bien con la recomendación de la función ''htmlspecialchars'', pero él y otros cometen un error, y yo seré enfático.

Un buen programador DEBE tener control sobre el uso o no de UTF-8 en sus cadenas y datos XML: UTF-8 (u otra codificación no ASCII) ES SEGURA en un algoritmo consistente.

SAFE UTF-8 XML NO NECESITA UN ENCODE DE ENTIDAD COMPLETA . La codificación indiscriminada produce "segunda clase, lectura no humana, codificar / decodificar demanda, XML". Y ASCII XML seguro, tampoco necesita codificación de entidad, cuando todo su contenido es ASCII.

Solo se deben escapar 3 o 4 caracteres en una cadena de contenido XML: > , < , & , y opcional " . Lea http://www.w3.org/TR/REC-xml/ " 2.4 Datos de caracteres y marcado "y" 4.6 Entidades Predefinidas ". ENTONCES USTED puede usar '' htmlentities() ''

Por ejemplo, la siguiente función de PHP hará que un XML sea completamente seguro:

// it is a didactic illustration, USE htmlentities($S,flag) function xmlsafe($s,$intoQuotes=0) { if ($intoQuotes) return str_replace(array(''&'',''>'',''<'',''"''), array(''&amp;'',''&gt;'',''&lt;'',''&quot;''), $s); // SAME AS htmlspecialchars($s) else return str_replace(array(''&'',''>'',''<''), array(''&amp;'',''&gt;'',''&lt;''), $s); // SAME AS htmlspecialchars($s,ENT_NOQUOTES) } // example of SAFE XML CONSTRUCTION function xmlTag( $element, $attribs, $contents = NULL) { $out = ''<'' . $element; foreach( $attribs as $name => $val ) $out .= '' ''.$name.''="''. xmlsafe( $val,1 ) .''"''; if ( $contents==='''' || is_null($contents) ) $out .= ''/>''; else $out .= ''>''.xmlsafe( $contents )."</$element>"; return $out; }

En un bloque CDATA no necesita usar esta función ... Pero, evite el uso indiscriminado de CDATA.


Pensé en agregar esto para aquellos que necesitan desinfectar y no perder los atributos XML.

// Returns SimpleXML Safe XML keeping the elements attributes as well function sanitizeXML($xml_content, $xml_followdepth=true){ if (preg_match_all(''%<((/w+)/s?.*?)>(.+?)<//2>%si'', $xml_content, $xmlElements, PREG_SET_ORDER)) { $xmlSafeContent = ''''; foreach($xmlElements as $xmlElem){ $xmlSafeContent .= ''<''.$xmlElem[''1''].''>''; if (preg_match(''%<((/w+)/s?.*?)>(.+?)<//2>%si'', $xmlElem[''3''])) { $xmlSafeContent .= sanitizeXML($xmlElem[''3''], false); }else{ $xmlSafeContent .= htmlspecialchars($xmlElem[''3''],ENT_NOQUOTES); } $xmlSafeContent .= ''</''.$xmlElem[''2''].''>''; } if(!$xml_followdepth) return $xmlSafeContent; else return "<?xml version=''1.0'' encoding=''UTF-8''?>".$xmlSafeContent; } else { return htmlspecialchars($xml_content,ENT_NOQUOTES); } }

Uso:

$body = <<<EG <?xml version=''1.0'' encoding=''UTF-8''?> <searchResult count="1"> <item> <title>2016 & Au Rendez-Vous Des Enfoir&</title> </item> </searchResult> EG; $newXml = sanitizeXML($body); var_dump($newXml);

Devoluciones:

<?xml version=''1.0'' encoding=''UTF-8''?> <searchResult count="1"> <item> <title>2016 &amp; Au Rendez-Vous Des Enfoir&amp;</title> </item> </searchResult>


Dom::createTextNode() escapará automáticamente de su contenido.

Ejemplo:

$dom = new DOMDocument; $element = $dom->createElement(''Element''); $element->appendChild( $dom->createTextNode(''I am text with Ünicödé & HTML €ntities ©'')); $dom->appendChild($element); echo $dom->saveXml();

Salida:

<?xml version="1.0"?> <Element>I am text with &#xDC;nic&#xF6;d&#xE9; &amp; HTML &#x20AC;ntities &#xA9;</Element>

Cuando configura la codificación interna para utf-8, por ejemplo

$dom->encoding = ''utf-8'';

todavía obtendrás

<?xml version="1.0" encoding="utf-8"?> <Element>I am text with Ünicödé &amp; HTML €ntities ©</Element>

Tenga en cuenta que lo anterior no es lo mismo que establecer el segundo argumento $value en Dom::createElement() . El método solo se asegurará de que los nombres de sus elementos sean válidos. Vea las Notas en la página del manual, ej.

$dom = new DOMDocument; $element = $dom->createElement(''Element'', ''I am text with Ünicödé & HTML €ntities ©''); $dom->appendChild($element); $dom->encoding = ''utf-8''; echo $dom->saveXml();

dará lugar a una advertencia

Warning: DOMDocument::createElement(): unterminated entity reference HTML €ntities ©

y el siguiente resultado:

<?xml version="1.0" encoding="utf-8"?> <Element>I am text with Ünicödé </Element>


htmlentities() no es una forma garantizada de construir XML legal.

Use htmlspecialchars() lugar de htmlentities() si esto es todo lo que le preocupa. Si tiene desajustes en la codificación entre la representación de sus datos y la codificación de su documento XML, htmlentities() puede servir para htmlentities() / cubrirlos (se aumentará el tamaño de su XML al hacerlo). Creo que es mejor hacer que las codificaciones sean consistentes y solo usar htmlspecialchars() .

Además, tenga en cuenta que si extrae el valor de retorno de htmlspecialchars() dentro de atributos XML delimitados con comillas simples, deberá pasar también el indicador ENT_QUOTES para que cualquier ENT_QUOTES simple en su cadena de origen también esté codificada correctamente. Sugiero hacer esto de todos modos, ya que hace que tu código sea inmune a los errores que resultan de que alguien use comillas simples para atributos XML en el futuro.

Editar: Para aclarar:

htmlentities() convertirá una cantidad de caracteres que no sean ANSI (supongo que esto es lo que quiere decir con los datos UTF-8) en entidades (que se representan solo con caracteres ANSI). Sin embargo, no puede hacerlo para ningún carácter que no tenga una entidad correspondiente y, por lo tanto, no puede garantizar que su valor de retorno esté formado únicamente por caracteres ANSI. Es por eso que estoy sugiriendo no usarlo.

Si la codificación es un problema posible, trátelo explícitamente (por ejemplo, con iconv() ).

Edición 2 : respuesta mejorada teniendo en cuenta el comentario de Josh Davis a continuación.