Преобразование HTML в обычный текст на PHP для электронной почты


Я использую TinyMCE, чтобы обеспечить минимальное форматирование текста на моем сайте. Из созданного HTML-кода я хотел бы преобразовать его в обычный текст для электронной почты. Я использовал класс под названием html2text, но ему действительно не хватает поддержки UTF-8, среди прочего. Мне, однако, нравится, что он сопоставляет определенные теги HTML с форматированием обычного текста - например, ставит подчеркивания вокруг текста, который ранее имел теги в HTML.

Использует ли кто-нибудь подобный подход к преобразование HTML в обычный текст на PHP? И если да, то рекомендуете ли вы какие-либо сторонние классы, которые я могу использовать? Или как вам лучше всего решить эту проблему?

Author: Benjamin, 2009-12-11

14 answers

Используйте html2text (пример HTML в текст ), лицензированный в соответствии с Публичной лицензией Eclipse . Он использует методы DOM PHP для загрузки из HTML, а затем повторяет полученный DOM для извлечения обычного текста. Использование:

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

Хотя он и неполный, он с открытым исходным кодом, и его вклад приветствуется.

Проблемы с другими сценариями преобразования:

  • Поскольку html2text (GPL) не совместим с EPL.
  • лкесслера ссылка (атрибуция) несовместима с большинством лицензий с открытым исходным кодом.
 87
Author: jevon, 2018-06-12 00:23:38

Есть надежная функция strip_tags. Хотя это не очень красиво. Это только обеззаразит. Вы можете объединить его с заменой строки, чтобы получить свои причудливые подчеркивания.


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

?>
 12
Author: pestilence669, 2009-12-11 01:46:23

Преобразование из HTML в текст с помощью DOMDocument является жизнеспособным решением. Рассмотрим HTML2Text, для которого требуется PHP5:

Что касается UTF-8, то в описании на странице "Как" говорится:

Собственная поддержка PHP юникода довольно слаба, и она не всегда правильно обрабатывайте utf-8. Хотя сценарий html2text использует безопасные для юникода методы (без использования модуля mbstring), он не всегда справляется с собственной обработкой кодировок PHP. PHP на самом деле не понимает юникод или кодировки, такие как utf-8, и использует базовую кодировку системы, которая, как правило, относится к семейству ISO-8859. В результате то, что может показаться вам допустимым символом в вашем текстовом редакторе, будь то utf-8 или однобайтовый, вполне может быть неверно истолковано PHP. Так что, хотя вы думаете, что вводите допустимый символ в html2text, но вполне возможно, что это не так.

Автор предлагает несколько подходов к решению этой проблемы и заявляет, что версия 2 HTML2Text (с использованием DOMDocument) имеет поддержку UTF-8.

Обратите внимание на ограничения для коммерческого использования.

 12
Author: lkessler, 2014-02-22 22:53:39

Вот еще одно решение:

$cleaner_input = strip_tags($text);

Для других вариантов функций дезинфекции см.:

Https://RunForgithub.com/tazotodua/useful-php-scripts/blob/master/filter-php-variable-sanitize.php

 8
Author: T.Todua, 2018-02-02 08:13:31

Для этого вы можете использовать lynx с параметрами -stdin и -dump:

<?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";
}
 7
Author: nad2000, 2012-03-08 02:32:04

Вы можете протестировать эту функцию

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);
}
 6
Author: HoangLong85, 2013-12-13 03:40:18

Я не нашел ни одного из существующих решений, подходящих - простые электронные письма в формате HTML для простых текстовых файлов.

Я открыл это хранилище, надеюсь, оно кому-то поможет. Лицензия MIT, кстати:)

Https://github.com/RobQuistNL/SimpleHtmlToText

Пример:

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

Возвращает:

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


Newlines
 4
Author: Rob Quist, 2016-11-21 20:19:43

Markdownify преобразует HTML в Markdown, систему форматирования обычного текста, используемую на этом самом сайте.

 2
Author: outis, 2011-12-28 10:14:19

Markdownify отлично сработал для меня! что следует упомянуть об этом: он отлично поддерживает utf-8, что было основной причиной, по которой я искал другое решение, кроме html2text (о чем упоминалось ранее в этой теме).

 1
Author: jebbie, 2012-05-14 18:01:55

Я столкнулся с той же проблемой, что и ОП, и попытка некоторых решений из приведенных выше ответов не сработала для моих сценариев. Посмотрите, почему в конце.

Вместо этого я нашел этот полезный скрипт, чтобы избежать путаницы, давайте назовем его html2text_roundcube, доступный под GPL:

На самом деле это обновленная версия уже упомянутого скрипта - http://www.chuggnutt.com/html2text.php - обновленного RoundCube почта.

Использование:

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

Почему html2text_roundcube оказался лучше других:

  • Скрипт http://www.chuggnutt.com/html2text.php не работал из коробки для случаев со специальными HTML-кодами/именами (например, &auml;) или непарными кавычками (например, <p>25" Monitor</p>).

  • У скрипта https://github.com/soundasleep/html2text не было возможности скрыть или сгруппировать ссылки в конце текста, из-за чего обычная HTML-страница выглядела раздутой ссылками, когда она была в текстовом формате; настройка кода для специальной обработки того, как выполняется преобразование, не является так же просто, как просто редактировать массив в html2text_roundcube.

 1
Author: Chris Dev, 2016-11-24 16:10:53

Я только что нашел PHP-функцию "strip_tags()" и она работает в моем случае.

Я попытался преобразовать следующий HTML:

<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>

После применения функции strip_tags() я получил следующий результат:

&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?
 0
Author: sudip, 2012-05-16 21:17:33

Если вы не хотите полностью удалять теги и сохранять содержимое внутри тегов, вы можете использовать DOMDocument и извлечь 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!

Одним из преимуществ этого подхода является то, что он не требует никаких внешних пакетов.

 0
Author: supersan, 2018-04-02 17:02:01

Если вы хотите преобразовать специальные символы HTML, а не просто удалить их, а также разобрать и подготовить к простому тексту, это было решение, которое сработало для меня...

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 с/ENT_QUOTES|ENT_XML1 преобразует такие вещи, как &#39; htmlspecialchars_decode преобразует такие вещи, как &amp; html_entity_decode преобразует такие вещи, как '&lt; , а strip_tags удаляет все оставшиеся HTML-теги.

 0
Author: Jay, 2018-05-15 14:36:04
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);

Выходной
строка 1
строка 2
строка 3
строка 4
строки 5

 0
Author: Aommy Indy, 2018-05-28 10:14:39