Konvertieren von HTML in einfachen Text in PHP für E-Mail

80

Ich verwende TinyMCE , um eine minimale Formatierung von Text auf meiner Website zu ermöglichen. Aus dem erstellten HTML-Code möchte ich ihn für E-Mails in einfachen Text konvertieren. Ich habe eine Klasse namens html2text verwendet , aber es fehlt unter anderem die UTF-8-Unterstützung. Ich finde es jedoch gut, dass bestimmte HTML-Tags der Nur-Text-Formatierung zugeordnet werden - beispielsweise das Unterstreichen von Text, der zuvor <i> Tags im HTML-Code hatte.

Verwendet jemand einen ähnlichen Ansatz zum Konvertieren von HTML in einfachen Text in PHP? Und wenn ja: Empfehlen Sie Klassen von Drittanbietern, die ich verwenden kann? Oder wie gehen Sie dieses Problem am besten an?

Justin Stayton
quelle
Als Referenz verweist Wikipedia auf eine Umfrage , bei der nur etwa 3% der Menschen nur Text-E-Mails verwenden.
Redzarf
7
@ Redzarf geht es nicht um diese 3%. Das Hinzufügen eines Nur-Text-Teils ist eine gute Idee, wenn Ihre E-Mail nicht direkt in den Spam-Ordner verschoben werden soll. Außerdem berücksichtigen diese 3% wahrscheinlich keine leichten mobilen Clients. Last but not least: 3% sind größer als 0%, was Sie dazu bringen sollte, ernsthaft darüber nachzudenken.
Ninj
@Ninj Ich habe gerade nachgesehen und die Umfrage war aus dem Jahr 2002, daher werden sich die Dinge seitdem geändert haben (obwohl ich immer noch denke, dass 3% wahrscheinlich richtig sind.) Guter Punkt zum Thema Spam - für alle, die dies später lesen und sich Sorgen um Spam machen, Ich fand, dass dieses Tool ausgezeichnet war: port25.com/support/authentication-center/email-verification
Redzarf

Antworten:

99

Verwenden Sie html2text (Beispiel HTML zu Text ), das unter der Eclipse Public License lizenziert ist . Es verwendet die DOM-Methoden von PHP, um aus HTML zu laden, und iteriert dann über das resultierende DOM, um einfachen Text zu extrahieren. Verwendung:

// 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);

Obwohl unvollständig, ist es Open Source und Beiträge sind willkommen.

Probleme mit anderen Konvertierungsskripten:

  • Da html2text (GPL) nicht EPL-kompatibel ist.
  • Der Link (Attribution) von lkessler ist mit den meisten Open Source-Lizenzen nicht kompatibel.
jevon
quelle
1
Das erste obige Skript wird unter der GPL veröffentlicht, bei der es sich nicht um eine "nichtkommerzielle" Lizenz handelt. Je nach Kontext kann es unerwünscht sein, aber es ist nicht "nicht kommerziell". Der zweite Link ermöglicht auch die kommerzielle Nutzung - nur mit Zuschreibung. Das ist auch nicht "nicht kommerziell".
Oliver Moran
1
@OliverMoran Sie haben Recht, ich habe die Antwort bearbeitet, um die Lizenzbeschränkungen genauer wiederzugeben.
Jevon
Danke @jevon, ich habe deine Arbeit in mein Projekt aufgenommen und es funktioniert großartig! Leider hat es nicht geholfen, mein Outlook-Problem zu lösen ( stackoverflow.com/questions/19135443/… ), aber auf diese Weise erhalte ich ein sauberes Ergebnis.
Ninj
Verbindung unterbrochen. Down-Voting.
Sibidharan
Bitte klären Sie, aber wer wird feststellen, ob jemand GLP verwendet oder nicht oder was auch immer?
Miguel
20

Hier ist eine andere Lösung:

$cleaner_input = strip_tags($text);

Weitere Varianten der Desinfektionsfunktionen finden Sie unter:

https://github.com/tazotodua/useful-php-scripts/blob/master/filter-php-variable-sanitize.php

T.Todua
quelle
12
Bessere Version$ClearText = preg_replace( "/\n\s+/", "\n", rtrim(html_entity_decode(strip_tags($HTMLText))) );
mAsT3RpEE
1
Das ist so einfach und braucht keine weitere Bibliothek. funktioniert auch sehr gut .......... :)
Mili
14

Die Konvertierung von HTML in Text mithilfe eines DOMDocument ist eine praktikable Lösung. Betrachten Sie HTML2Text, für das PHP5 erforderlich ist:

In Bezug auf UTF-8 heißt es in der Beschreibung auf der Seite "Howto":

Die Unterstützung von PHP für Unicode ist ziemlich schlecht und es wird utf-8 nicht immer richtig verarbeitet. Obwohl das Skript html2text Unicode-sichere Methoden verwendet (ohne das Modul mbstring zu benötigen), kann es nicht immer mit PHPs eigener Handhabung von Codierungen umgehen. PHP versteht Unicode oder Codierungen wie utf-8 nicht wirklich und verwendet die Basiscodierung des Systems, das tendenziell zur ISO-8859-Familie gehört. Infolgedessen kann das, was für Sie wie ein gültiges Zeichen in Ihrem Texteditor aussieht, entweder in utf-8 oder in Einzelbyte, von PHP möglicherweise falsch interpretiert werden. Obwohl Sie glauben, ein gültiges Zeichen in html2text einzugeben, ist dies möglicherweise nicht der Fall.

Der Autor bietet verschiedene Lösungsansätze an und gibt an, dass Version 2 von HTML2Text (mit DOMDocument) UTF-8-Unterstützung bietet.

Beachten Sie die Einschränkungen für die kommerzielle Nutzung.

lkessler
quelle
Markdownify wird nicht mehr gepflegt. Die Online-Demo gibt viele Warnungen aus und funktioniert nicht. Die neue Version von html2text funktioniert für meine E-Mail. Ein spätes +1 zu lkessler.
Malcanso
13

Es gibt die vertrauenswürdige Funktion strip_tags . Es ist aber nicht schön. Es wird nur desinfizieren. Sie können es mit einem String-Ersatz kombinieren, um Ihre ausgefallenen Unterstriche zu erhalten.


<?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)));

?>
Pest669
quelle
Vergessen Sie nicht, dass Strip-Tags auch Anker entfernen!
Alix Axel
9

Sie können lynx mit den Optionen -stdin und -dump verwenden, um dies zu erreichen:

<?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";
}
nad2000
quelle
8

Sie können diese Funktion testen

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);
}
HoangLong85
quelle
Danke dafür. Hat für meine Verwendung hervorragend funktioniert (Konvertieren von HTML für einen RSS-Feed) und eine einfache Vorlage zum Hinzufügen von zwei zusätzlichen Fällen (& rsquo; und & mdash;) bereitgestellt.
Alan M.
6

Ich fand keine der vorhandenen Lösungen passend - einfache HTML-E-Mails zu einfachen Nur-Text-Dateien.

Ich habe dieses Repository geöffnet und hoffe, es hilft jemandem. MIT-Lizenz übrigens :)

https://github.com/RobQuistNL/SimpleHtmlToText

Beispiel:

$myHtml = '<b>This is HTML</b><h1>Header</h1><br/><br/>Newlines';
echo (new Parser())->parseString($myHtml);

kehrt zurück:

**This is HTML**
### Header ###


Newlines
rauben
quelle
Für Länge und Inhalt als minderwertig gekennzeichnet. Ich weiß nicht. Vielleicht sollte der Beitrag etwas darüber aussagen, wie Ihr Code zur Beantwortung des Problems verwendet werden kann, oder es sollte ein Kommentar sein. Die beliebtesten Antworten scheinen zu zeigen, wie Lösungen aus PHP-Code heraus aufgerufen werden können.
Bill Bell
Es tut mir leid, dass ich diese Bibliothek geschrieben habe. Ich habe ein kleines Beispiel für Sie hinzugefügt, wenn Sie nicht auf den Link klicken und sich das Beispiel ansehen möchten.
Rob
2
Tut mir nicht leid! :-) Ich habe als SO-Rezensent geschrieben. Es ist nicht so, dass ich nicht auf den Link klicken wollte. Es sind SO-Antworten, die dies erfordern und als minderwertig gelten. Ich weiß nicht, warum irgendjemand Ihre Antwort im Übrigen ablehnen würde.
Bill Bell
4

Wenn Sie die HTML-Sonderzeichen konvertieren und nicht nur entfernen, sondern auch entfernen und sich auf einfachen Text vorbereiten möchten, war dies die Lösung, die für mich funktioniert hat ...

function htmlToPlainText($str){
    $str = str_replace('&nbsp;', ' ', $str);
    $str = html_entity_decode($str, ENT_QUOTES | ENT_COMPAT , 'UTF-8');
    $str = html_entity_decode($str, ENT_HTML5, 'UTF-8');
    $str = html_entity_decode($str);
    $str = htmlspecialchars_decode($str);
    $str = strip_tags($str);

    return $str;
}

$string = '<p>this is (&nbsp;) a test</p>
<div>Yes this is! &amp; does it get "processed"? </div>'

htmlToPlainText($string);
// "this is ( ) a test. Yes this is! & does it get processed?"`

html_entity_decode w / ENT_QUOTES | ENT_XML1 konvertiert Dinge wie &#39; htmlspecialchars_decode konvertiert Dinge wie &amp; html_entity_decode konvertiert Dinge wie '&lt; und strip_tags entfernt alle verbleibenden HTML-Tags.

Jay
quelle
3

Markdownify konvertiert HTML in Markdown, ein Nur-Text-Formatierungssystem, das auf dieser Site verwendet wird.

outis
quelle
Eine gute Wahl, außer wie es mit Links umgeht. Probieren Sie die Online-Demo aus, wenn Sie darüber nachdenken.
Redzarf
3
public function plainText($text)
{
    $text = strip_tags($text, '<br><p><li>');
    $text = preg_replace ('/<[^>]*>/', PHP_EOL, $text);

    return $text;
}

$text = "string 1<br>string 2<br/><ul><li>string 3</li><li>string 4</li></ul><p>string 5</p>";

echo planText($text);

Ausgabezeichenfolge
1
Zeichenfolge 2
Zeichenfolge 3
Zeichenfolge 4
Zeichenfolge 5

Aommy Indy
quelle
1
füge nicht nur eine Antwort hinzu. Bitte fügen Sie Text hinzu, warum dies Antwort ist
Himanth
2

Ich bin auf dasselbe Problem wie das OP gestoßen, und einige Lösungen aus den obigen Top-Antworten haben sich für meine Szenarien nicht bewährt. Sehen Sie am Ende, warum.

Stattdessen fand ich dieses hilfreiche Skript, um Verwirrung zu vermeiden, nennen wir es html2text_roundcube, verfügbar unter GPL:

Es ist tatsächlich eine aktualisierte Version eines bereits erwähnten Skripts - http://www.chuggnutt.com/html2text.php- aktualisiert durch RoundCube Mail.

Verwendung:

$h2t = new \Html2Text\Html2Text('Hello, &quot;<b>world</b>&quot;');
echo $h2t->getText(); // prints Hello, "WORLD"

Warum html2text_roundcubeerwies es sich als besser als die anderen:

  • In http://www.chuggnutt.com/html2text.phpFällen mit speziellen HTML-Codes / Namen (z. B. &auml;) oder ungepaarten Anführungszeichen (z <p>25" Monitor</p>. B. ) funktionierte das Skript nicht sofort .

  • Das Skript https://github.com/soundasleep/html2texthatte keine Möglichkeit, die Links am Ende des Textes auszublenden oder zu gruppieren, sodass eine normale HTML-Seite im Nur-Text-Format mit Links überfüllt aussieht. Das Anpassen des Codes für eine spezielle Behandlung der Transformation ist nicht so einfach wie das einfache Bearbeiten eines Arrays in html2text_roundcube.

Chris Dev
quelle
1

Ich habe gerade eine PHP-Funktion "strip_tags ()" gefunden und sie funktioniert in meinem Fall.

Ich habe versucht, den folgenden HTML-Code zu konvertieren:

<p><span style="font-family: 'Verdana','sans-serif'; color: black; font-size: 7.5pt;">&nbsp;</span>Many  practitioners are optimistic that the eyeglass and contact lens  industry will recover from the recent economic storm. Did your practice  feel its affects?&nbsp; Statistics show revenue notably declined in 2008 and  2009. But interestingly enough, those that monitor these trends state  that despite the industry's lackluster performance during this time,  revenue has grown at an average annual rate&nbsp;of 2.2% over the last five  years, to $9.0 billion in 2010.&nbsp; So despite the downturn, how were we  able to manage growth as an industry?</p>

Nach dem Anwenden der Funktion strip_tags () habe ich die folgende Ausgabe:

&amp;nbsp;Many  practitioners are optimistic that the eyeglass and contact lens  industry will recover from the recent economic storm. Did your practice  feel its affects?&amp;nbsp; Statistics show revenue notably declined in 2008 and  2009. But interestingly enough, those that monitor these trends state  that despite the industry&#039;s lackluster performance during this time,  revenue has grown at an average annual rate&amp;nbsp;of 2.2% over the last five  years, to $9.0 billion in 2010.&amp;nbsp; So despite the downturn, how were we  able to manage growth as an industry?
Sudip
quelle
3
strip_tags () behandelt keinen Fall, in dem Sie mehrere Elemente in mehreren Zeilen haben, die von HTML als "Inline" betrachtet werden, und zeigt sie in mehreren Zeilen an. Auch der umgekehrte Fall: Wenn Sie mehrere div-Elemente in einer Zeile haben, werden die Tags entfernt und der Inhalt verkettet. Ich habe meine Erfahrungen hier geteilt: stackoverflow.com/questions/1930297/…
Nikola Petkanski
1

Für Texte in utf-8 hat es bei mir mb_convert_encoding funktioniert. Stellen Sie sicher, dass Sie das "@" verwenden, um alles unabhängig von Fehlern zu verarbeiten.

Der grundlegende Code, den ich verwende, ist:

$dom = new DOMDocument();
@$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));

$body = $dom->getElementsByTagName('body')->item(0);
echo $body->textContent;

Wenn Sie etwas Fortgeschritteneres wünschen, können Sie die Knoten iterativ analysieren, aber Sie werden auf viele Probleme mit Leerzeichen stoßen.

Ich habe einen Konverter implementiert, der auf dem basiert, was ich hier sage. Wenn Sie interessiert sind, können Sie es von git https://github.com/kranemora/html2text herunterladen

Es kann als Referenz dienen, um Ihre zu machen

Sie können es so verwenden:

$html = <<<EOF
<p>Welcome to <strong>html2text<strong></p>
<p>It's <em>works</em> for you?</p>
EOF;

$html2Text = new \kranemora\Html2Text\Html2Text;
$text = $html2Text->convert($html);
Fernando Pita
quelle
0

Wenn Sie die Tags nicht vollständig entfernen und den Inhalt in den Tags behalten möchten, können Sie den Stammknoten wie folgt verwenden DOMDocumentund extrahieren textContent:

function html2text($html) {
    $dom = new DOMDocument();
    $dom->loadHTML("<body>" . strip_tags($html, '<b><a><i><div><span><p>') . "</body>");
    $xpath = new DOMXPath($dom);
    $node = $xpath->query('body')->item(0);
    return $node->textContent; // text
}

$p = 'this is <b>test</b>. <p>how are <i>you?</i>. <a href="#">I\'m fine!</a></p>';
print html2text($p);
// this is test. how are you?. I'm fine!

Ein Vorteil dieses Ansatzes besteht darin, dass keine externen Pakete erforderlich sind.

Supersan
quelle