82 votes

Conversion de HTML en texte brut en PHP pour le courrier électronique

J'utilise TinyMCE pour permettre un formatage minimal du texte sur mon site. À partir du HTML produit, j'aimerais le convertir en texte brut pour le courrier électronique. J'ai utilisé une classe appelée html2text mais il lui manque le support de l'UTF-8, entre autres. Cependant, j'apprécie le fait qu'il permette de convertir certaines balises HTML en formatage de texte brut - comme mettre des traits de soulignement autour d'un texte qui avait auparavant des balises <i> dans le HTML.

Quelqu'un utilise-t-il une approche similaire pour convertir du HTML en texte brut en PHP ? Et si oui : Recommandez-vous des classes tierces que je pourrais utiliser ? Ou bien, quelle est la meilleure façon d'aborder ce problème ?

0 votes

4 votes

0 votes

Pour référence, wikipedia liens vers une enquête Cela dit, seulement 3 % des gens utilisent des courriels en mode texte seulement.

103voto

jevon Points 1162

Utilisez html2text (exemple HTML à texte ), sous licence de la Licence publique Eclipse . Il utilise les méthodes DOM de PHP pour charger du HTML, et ensuite itère sur le DOM résultant pour extraire du texte brut. Utilisation :

// when installed using the Composer package
$text = Html2Text\Html2Text::convert($html);

// usage when installed using html2text.php
require('html2text.php');
$text = convert_html_to_text($html);

Bien qu'incomplet, il s'agit d'une source ouverte et les contributions sont les bienvenues.

Problèmes avec d'autres scripts de conversion :

  • Depuis html2text (GPL) n'est pas compatible avec l'EPL.
  • Lien de lkessler (attribution) est incompatible avec la plupart des licences de logiciels libres.

1 votes

Le premier script ci-dessus est publié sous la licence GPL, qui est pas une licence "non-commerciale". Selon le contexte, cela peut être indésirable, mais ce n'est pas "non commercial". Le deuxième lien permet également une utilisation commerciale, mais avec une attribution. Ce n'est pas non plus "non commercial".

1 votes

@OliverMoran Vous avez raison, j'ai modifié la réponse pour refléter plus précisément les limitations de leur licence.

0 votes

Merci @jevon, j'ai inclus votre travail dans mon projet et cela fonctionne très bien ! Malheureusement, cela n'a pas aidé à résoudre mon problème Outlook ( stackoverflow.com/questions/19135443/ ) mais j'obtiens un résultat propre de cette façon.

14voto

lkessler Points 11143

Conversion de HTML en texte à l'aide d'un DOMDocument est une solution viable. Considérez HTML2Text, qui nécessite PHP5 :

En ce qui concerne UTF-8, le texte de la page "howto" indique :

Le support de l'unicode par PHP est assez pauvre, et il ne gère pas toujours correctement l'utf-8. Bien que le script de html2text utilise des méthodes sûres pour l'unicode (sans avoir besoin du module mbstring), il ne peut pas toujours gérer les encodages propres à PHP. PHP ne comprend pas vraiment l'unicode ou les encodages comme utf-8, et utilise l'encodage de base du système, qui tend à être celui de la famille ISO-8859. Par conséquent, ce qui peut vous sembler être un caractère valide dans votre éditeur de texte, que ce soit en utf-8 ou en single-byte, peut être mal interprété par PHP. Ainsi, même si vous pensez avoir entré un caractère valide dans html2text, il se peut que ce ne soit pas le cas.

L'auteur propose plusieurs approches pour résoudre ce problème et indique que la version 2 de HTML2Text (utilisant DOMDocument) prend en charge UTF-8.

Notez les restrictions pour l'utilisation commerciale.

0 votes

Markdownify n'est plus maintenu ; la démo en ligne affiche de nombreux avertissements et ne fonctionne pas. La nouvelle version de html2text fonctionne pour mon courriel. Un +1 tardif à lkessler.

13voto

pestilence669 Points 4009

Il y a le fidèle strip_tags fonction. Mais ce n'est pas joli. Ça ne fait que désinfecter. Vous pourriez la combiner avec un remplacement de chaîne de caractères pour obtenir vos caractères de soulignement fantaisistes.

<?php
// to strip all tags and wrap italics with underscore
strip_tags(str_replace(array("<i>", "</i>"), array("_", "_"), $text));

// to preserve anchors...
str_replace("|a", "<a", strip_tags(str_replace("<a", "|a", $text)));

?>

0 votes

N'oubliez pas que la suppression des balises supprime également les ancres !

9voto

nad2000 Points 1247

Vous pouvez utiliser lynx avec les options -stdin et -dump pour y parvenir :

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => array("file", "/tmp/htmp2txt.log", "a") // stderr is a file to write to
);

$process = proc_open('lynx -stdin -dump 2>&1', $descriptorspec, $pipes, '/tmp', NULL);

if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // Any error output will be appended to htmp2txt.log

    $stdin = $pipes[0];
    fwrite($stdin,  <<<'EOT'
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <title>TEST</title>
</head>
<body>
<h1><span>Lorem Ipsum</span></h1>

<h4>"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..."</h4>
<h5>"There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."</h5>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque et sapien ut erat porttitor suscipit id nec dui. Nam rhoncus mauris ac dui tristique bibendum. Aliquam molestie placerat gravida. Duis vitae tortor gravida libero semper cursus eu ut tortor. Nunc id orci orci. Suspendisse potenti. Phasellus vehicula leo sed erat rutrum sed blandit purus convallis.
</p>
<p>
Aliquam feugiat, neque a tempus rhoncus, neque dolor vulputate eros, non pellentesque elit lacus ut nunc. Pellentesque vel purus libero, ultrices condimentum lorem. Nam dictum faucibus mollis. Praesent adipiscing nunc sed dui ultricies molestie. Quisque facilisis purus quis felis molestie ut accumsan felis ultricies. Curabitur euismod est id est pretium accumsan. Praesent a mi in dolor feugiat vehicula quis at elit. Mauris lacus mauris, laoreet non molestie nec, adipiscing a nulla. Nullam rutrum, libero id pellentesque tempus, erat nibh ornare dolor, id accumsan est risus at leo. In convallis felis at eros condimentum adipiscing aliquam nisi faucibus. Integer arcu ligula, porttitor in fermentum vitae, lacinia nec dui.
</p>
</body>
</html>
EOT
    );
    fclose($stdin);

    echo stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
}

8voto

user3097937 Points 31

Vous pouvez tester cette fonction

function html2text($Document) {
    $Rules = array ('@<script[^>]*?>.*?</script>@si',
                    '@<[\/\!]*?[^<>]*?>@si',
                    '@([\r\n])[\s]+@',
                    '@&(quot|#34);@i',
                    '@&(amp|#38);@i',
                    '@&(lt|#60);@i',
                    '@&(gt|#62);@i',
                    '@&(nbsp|#160);@i',
                    '@&(iexcl|#161);@i',
                    '@&(cent|#162);@i',
                    '@&(pound|#163);@i',
                    '@&(copy|#169);@i',
                    '@&(reg|#174);@i',
                    '@&#(d+);@e'
             );
    $Replace = array ('',
                      '',
                      '',
                      '',
                      '&',
                      '<',
                      '>',
                      ' ',
                      chr(161),
                      chr(162),
                      chr(163),
                      chr(169),
                      chr(174),
                      'chr()'
                );
  return preg_replace($Rules, $Replace, $Document);
}

0 votes

Merci pour cela. Cela a très bien fonctionné pour mon utilisation (conversion de HTML pour un flux RSS), et a fourni un modèle simple pour ajouter deux cas supplémentaires (&rsquo ; et &mdash ;).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X