2010-09-16 1 views
6

J'ai cette fonction pour assurer que chaque img tag a URL absolue:Existe-t-il un moyen de conserver les entités intactes lors de l'analyse de html avec DomDocument?

function absoluteSrc($html, $encoding = 'utf-8') 
{ 
    $dom = new DOMDocument(); 
    // Workaround to use proper encoding 
    $prehtml = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset={$encoding}\"></head><body>"; 
    $posthtml = "</body></html>"; 

    if($dom->loadHTML($prehtml . trim($html) . $posthtml)){ 
     foreach($dom->getElementsByTagName('img') as $img){ 
      if($img instanceof DOMElement){ 
       $src = $img->getAttribute('src'); 
       if(strpos($src, 'http://') !== 0){ 
        $img->setAttribute('src', 'http://my.server/' . $src); 
       } 
      } 
     } 

     $html = $dom->saveHTML(); 

     // Remove remains of workaround/DomDocument additions 
     $cut_start = strpos($html, '<body>') + 6; 
     $cut_length = -1 * (1+strlen($posthtml)); 
     $html = substr($html, $cut_start, $cut_length); 
    } 
    return $html; 
} 

Il fonctionne très bien, mais il retourne les entités décodées comme des caractères unicode

$html = <<< EOHTML 
<p><img src="images/lorem.jpg" alt="lorem" align="left"> 
Lorem ipsum dolor sit amet consectetuer Nullam felis laoreet 
Cum magna. Suscipit sed vel tincidunt urna.<br> 
Vel consequat pretium Curabitur faucibus justo adipiscing elit. 
<img src="others/ipsum.png" alt="ipsum" align="right"></p> 

<center>&copy; Dr&nbsp;Jekyll &#38; Mr&nbsp;Hyde</center> 
EOHTML; 

echo absoluteSrc($html); 

Sorties:

<p><img src="http://my.server/images/lorem.jpg" alt="lorem" align="left"> 
Lorem ipsum dolor sit amet consectetuer Nullam felis laoreet 
Cum magna. Suscipit sed vel tincidunt urna.<br> 
Vel consequat pretium Curabitur faucibus justo adipiscing elit. 
<img src="http://my.server/others/ipsum.png" alt="ipsum" align="right"></p> 

<center>© Dr Jekyll &amp; Mr Hyde</center> 

Comme vous pouvez le voir sur la dernière ligne

  • & copie; est traduit en © (U + 00A9),
  • & nbsp; à l'espace insécable (U + 00A0),
  • & # 38; à & amp;

Je voudrais qu'ils restent les mêmes que dans la chaîne d'entrée.

+0

J'aimerais aussi connaître la réponse à cette question. J'ai fini par convertir &..; entités en ** ENTITY -...- ENTITY ** avant d'analyser et de reconvertir après que cela soit fait. –

+1

Je l'ai simplifié pour remplacer seulement l'ampli 'str_replace ('&', '^ amp ^', $ html)', 'str_replace ('^ amp ^', '&', $ html)' et ça marche, merci! S'il vous plaît postez comme une réponse afin qu'il puisse être accepté s'il n'y a pas d'autre moyen non-kludgey –

+0

Peut-être que c'est le coupable: http://nl2.php.net/manual/fr/class.domdocument.php#domdocument.props .substitutionnalités (test dans un instant ...) – Wrikken

Répondre

0

J'aimerais aussi connaître la réponse à cette question.

J'ai fini par convertir & ..; entités à **ENTITY-...-ENTITY** avant d'analyser et de reconvertir après que cela soit fait.

1

Le code suivant semble fonctionner

$dom= new DOMDocument('1.0', 'UTF-8'); 
    $dom->loadHTML($this->htmlentities2stringcode(rawurldecode($content))); 
    $dom->preserveWhiteSpace = true; 

    $innerHTML = str_replace("<html></html><html><body>", "", 
    str_replace("</body></html>", "", 
str_replace("+","%2B",str_replace("<p></p>", "", $this->getInnerHTML($dom))))); 

    return $this->stringcode2htmlentities($innerHTML)); 
} 
// ---------------------------------------------------------- 
function htmlentities2stringcode($string) { 
    // This method will convert htmlentities such as &copy; into the pseudo string version ^copy^; etc 
     $from = array_keys($this->getHTMLEntityStringCodeArray()); 
     $to  = array_values($this->getHTMLEntityStringCodeArray()); 
    return str_replace($from, $to, $string); 
} 
// ---------------------------------------------------------- 
function stringcode2htmlentities ($string) { 
    // This method will convert pseudo string such as ^copy^ to the original html entity &copy; etc 
    $from = array_values($this->getHTMLEntityStringCodeArray()); 
    $to  = array_keys($this->getHTMLEntityStringCodeArray()); 
    return str_replace($from, $to, $string); 
    } 
    // ------------------------------------------------------------- 
    function getHTMLEntityStringCodeArray() { 

     return array('&Alpha;'=>'^Alpha^', 
            '&Beta;'=>'^Beta^', 
            '&Chi;'=>'^Chi^', 
            '&Dagger;'=>'^Dagger^', 
            '&Delta;'=>'^Delta^', 
            '&Epsilon;'=>'^Epsilon^', 
            '&Eta;'=>'^Eta^', 
            '&Gamma;'=>'^Gamma^', 
            '&Iota;'=>'^lota^', 
            '&Kappa;'=>'^Kappa^', 
            '&Lambda;'=>'^Lambda^', 
            '&Mu;'=>'^Mu^', 
            '&Nu;'=>'^Nu^', 
            '&OElig;'=>'^OElig^', 
            '&Omega;'=>'^Omega^', 
            '&Omicron;'=>'^Omicron^', 
            '&Phi;'=>'^Phi^', 
            '&Pi;'=>'^Pi^', 
            '&Prime;'=>'^Prime^', 
            '&Psi;'=>'^Psi^', 
            '&Rho;'=>'^Rho^', 
            '&Scaron;'=>'^Scaron^', 
            '&Scaron;'=>'^Scaron^', 
            '&Sigma;'=>'^Sigma^', 
            '&Tau;'=>'^Tau^', 
            '&Theta;'=>'^Theta^', 
            '&Upsilon;'=>'^Upsilon^', 
            '&Xi;'=>'^Xi^', 
            '&Yuml;'=>'^Yuml^', 
            '&Zeta;'=>'^Zeta^', 
            '&alefsym;'=>'^alefsym^', 
            '&alpha;'=>'^alpha^', 
            '&and;'=>'^and^', 
            '&ang;'=>'^ang^', 
            '&asymp;'=>'^asymp^', 
            '&bdquo;'=>'^bdquo^', 
            '&beta;'=>'^beta^', 
            '&bull;'=>'^bull^', 
            '&cap;'=>'^cap^', 
            '&chi;'=>'^chi^', 
            '&circ;'=>'^circ^', 
            '&clubs;'=>'^clubs^', 
            '&cong;'=>'^cong^', 
            '&crarr;'=>'^crarr^', 
            '&cup;'=>'^cup^', 
            '&dArr;'=>'^dArr^', 
            '&dagger;'=>'^dagger^', 
            '&darr;'=>'^darr^', 
            '&delta;'=>'^delta^', 
            '&diams;'=>'^diams^', 
            '&empty;'=>'^empty^', 
            '&emsp;'=>'^emsp^', 
            '&ensp;'=>'^ensp^', 
            '&epsilon;'=>'^epsilon^', 
            '&equiv;'=>'^equiv^', 
            '&eta;'=>'^eta^', 
            '&euro;'=>'^euro^', 
            '&exist;'=>'^exist^', 
            '&fnof;'=>'^fnof^', 
            '&forall;'=>'^forall^', 
            '&frasl;'=>'^frasl^', 
            '&gamma;'=>'^gamma^', 
            '&ge;'=>'^ge^', 
            '&hArr;'=>'^hArr^', 
            '&harr;'=>'^harr^', 
            '&hearts;'=>'^hearts^', 
            '&hellip;'=>'^hellip^', 
            '&image;'=>'^image^', 
            '&infin;'=>'^infin^', 
            '&int;'=>'^int^', 
            '&iota;'=>'^iota^', 
            '&isin;'=>'^isin^', 
            '&kappa;'=>'^kappa^', 
            '&lArr;'=>'^lArr^', 
            '&lambda;'=>'^lambda^', 
            '&lang;'=>'^lang^', 
            '&larr;'=>'^larr^', 
            '&lceil;'=>'^lceil^', 
            '&ldquo;'=>'^ldquo^', 
            '&le;'=>'^le^', 
            '&lfloor;'=>'^lfloor^', 
            '&lowast;'=>'^lowast^', 
            '&loz;'=>'^loz^', 
            '&lrm;'=>'^lrm^', 
            '&lsaquo;'=>'^lsaquo^', 
            '&lsquo;'=>'^lsquo^', 
            '&mdash;'=>'^mdash^', 
            '&minus;'=>'^minus^', 
            '&mu;'=>'^mu^', 
            '&nabla;'=>'^nabla^', 
            '&ndash;'=>'^ndash^', 
            '&ne;'=>'^ne^', 
            '&ni;'=>'^ni^', 
            '&notin;'=>'^notin^', 
            '&nsub;'=>'^nsub^', 
            '&nu;'=>'^nu^', 
            '&oelig;'=>'^oelig^', 
            '&oline;'=>'^oline^', 
            '&omega;'=>'^omega^', 
            '&omicron;'=>'^omicron^', 
            '&oplus;'=>'^oplus^', 
            '&or;'=>'^or^', 
            '&otimes;'=>'^otimes^', 
            '&part;'=>'^part^', 
            '&permil;'=>'^permil^', 
            '&perp;'=>'^perp^', 
            '&phi;'=>'^phi^', 
            '&pi;'=>'^pi^', 
            '&piv;'=>'^piv^', 
            '&prime;'=>'^prime^', 
            '&prod;'=>'^prod^', 
            '&prop;'=>'^prop^', 
            '&psi;'=>'^psi^', 
            '&rArr;'=>'^rArr^', 
            '&radic;'=>'^radic^', 
            '&rang;'=>'^rang^', 
            '&rarr;'=>'^rarr^', 
            '&rceil;'=>'^rceil^', 
            '&rdquo;'=>'^rdquo^', 
            '&real;'=>'^real^', 
            '&rfloor;'=>'^rfloor^', 
            '&rho;'=>'^rho^', 
            '&rlm;'=>'^rlm^', 
            '&rsaquo;'=>'^rsaquo^', 
            '&rsquo;'=>'^rsquo^', 
            '&sbquo;'=>'^sbquo^', 
            '&scaron;'=>'^scaron^', 
            '&sdot;'=>'^sdot^', 
            '&sigma;'=>'^sigma^', 
            '&sigmaf;'=>'^sigmaf^', 
            '&sim;'=>'^sim^', 
            '&spades;'=>'^spades^', 
            '&sub;'=>'^sub^', 
            '&sube;'=>'^sube^', 
            '&sum;'=>'^sum^', 
            '&sup;'=>'^sup^', 
            '&supe;'=>'^supe^', 
            '&tau;'=>'^tau^', 
            '&there4;'=>'^there4^', 
            '&theta;'=>'^thetasym^', 
            '&thetasym;'=>'^thetasym^', 
            '&thinsp;'=>'^thinsp^', 
            '&tilde;'=>'^tilde^', 
            '&trade;'=>'^trade^', 
            '&uArr;'=>'^uArr^', 
            '&uarr;'=>'^uarr^', 
            '&upsih;'=>'^upsih^', 
            '&upsilon;'=>'^upsilon^', 
            '&weierp;'=>'^weierp^', 
            '&xi;'=>'^xi^', 
            '&yuml;'=>'^yuml^', 
            '&zeta;'=>'^zeta^', 
            '&zwj;'=>'^zwj^', 
            '&zwnj;'=>'^zwnj^'); 
    } 
0

Une solution alternative consiste à utiliser DOMDocument-> saveHTMLFile() (qui ne convertit pas les entités HTML) et lire le contenu du fichier enregistré dans une chaîne .

Ce n'est pas super joli, mais il a l'avantage de ne pas avoir à trouver et remplacer manuellement vous-même les codes d'entité (deux fois), comme d'autres solutions proposées ici.

Questions connexes