이메일 용 PHP에서 HTML을 일반 텍스트로 변환


80

저는 TinyMCE 를 사용 하여 내 사이트 내에서 최소한의 텍스트 서식을 허용합니다. 생성 된 HTML에서 전자 메일 용 일반 텍스트로 변환하고 싶습니다. 나는 html2text 라는 클래스를 사용해 왔지만 다른 것들 중에서도 UTF-8 지원이 정말 부족합니다. 그러나 저는 특정 HTML 태그를 일반 텍스트 형식으로 매핑합니다. 예를 들어 이전에 HTML에서 <i> 태그가 있었던 텍스트 주위에 밑줄을 넣는 것과 같습니다.

누구든지 PHP에서 HTML을 일반 텍스트로 변환하는 유사한 접근 방식을 사용합니까? 그렇다면 : 내가 사용할 수있는 타사 클래스를 추천합니까? 아니면이 문제를 어떻게 가장 잘 해결합니까?



4
html2text에는 무서운 코드 실행 취약점이 있습니다.
Tgr

참고로, 위키피디아 는 약 3 %의 사람들 만이 텍스트 전용 이메일을 사용한다고 답한 설문 조사에 연결되어 있습니다.
Redzarf 2013-08-13

8
@Redzarf는이 3 %에 관한 것이 아닙니다. 이메일이 스팸 폴더로 직접 이동하지 않도록하려면 일반 텍스트 부분을 추가하는 것이 좋습니다. 또한이 3 %는 가벼운 모바일 클라이언트를 고려하지 않았을 것입니다. 마지막으로 중요한 점 : 3 %는 0 %보다 크므로 심각하게 고려해야합니다.
Ninj

@Ninj 방금 확인한 설문 조사는 2002 년부터 였으므로 그 이후로 상황이 바뀌었을 것입니다 (아마도 3 %가 옳다고 생각합니다.) 스팸 문제에 대한 좋은 점-나중에이 내용을 읽고 스팸에 대해 우려하는 모든 사람에게, 이 도구가 훌륭하다는 것을 발견했습니다 : port25.com/support/authentication-center/email-verification
Redzarf

답변:


99

Eclipse Public License에 따라 라이센스가 부여 된 html2text (예제 HTML to text ) 를 사용하십시오 . PHP의 DOM 메서드를 사용하여 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-호환되지 않습니다.
  • lkessler의 링크 (속성)는 대부분의 오픈 소스 라이선스와 호환되지 않습니다.

1
위의 첫 번째 스크립트 는 "비 상업용"라이선스 가 아닌 GPL에 따라 배포되었습니다 . 상황에 따라 바람직하지 않을 수 있지만 "비 상업용"은 아닙니다. 두 번째 링크는 저작자 표시만으로 상업적 사용을 허용합니다. 그것도 "비영리적"이 아닙니다.
Oliver Moran

1
@OliverMoran 당신이 맞습니다, 나는 그들의 라이센스 제한을 더 정확하게 반영하기 위해 대답을 편집했습니다.
jevon

@jevon 감사합니다. 내 프로젝트에 귀하의 작업을 포함 시켰으며 훌륭하게 작동합니다! 불행히도 내 Outlook 문제를 해결하는 데 도움이되지는 않았지만 ( stackoverflow.com/questions/19135443/… ) 그런 식으로 깨끗한 결과를 얻습니다.
Ninj

링크가 끊어졌습니다. 하향 투표.
Sibidharan

명확하게 해주세요.하지만 누군가 GLP 등에서 사용 중인지 여부를 누가 감지할까요?
Miguel

21

여기 또 다른 해결책이 있습니다.

$cleaner_input = strip_tags($text);

살균 기능의 다른 변형은 다음을 참조하십시오.

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


13
더 나은 버전$ClearText = preg_replace( "/\n\s+/", "\n", rtrim(html_entity_decode(strip_tags($HTMLText))) );
mAsT3RpEE 2014 년

1
이것은 매우 간단하고 다른 라이브러리가 필요하지 않습니다. 또한 매우 잘 작동합니다 .......... :)
mili

14

DOMDocument를 사용하여 HTML에서 텍스트로 변환 하는 것은 실행 가능한 솔루션입니다. PHP5가 필요한 HTML2Text를 고려하십시오.

UTF-8과 관련하여 "howto"페이지의 글에는 다음과 같은 내용이 있습니다.

유니 코드에 대한 PHP의 자체 지원은 매우 열악하며 항상 utf-8을 올바르게 처리하지는 않습니다. html2text 스크립트는 mbstring 모듈이 필요없는 유니 코드 안전 메서드를 사용하지만 항상 PHP의 자체 인코딩 처리에 대처할 수는 없습니다. PHP는 utf-8과 같은 유니코 드나 인코딩을 실제로 이해하지 못하며 시스템의 기본 인코딩을 사용합니다. 이는 ISO-8859 제품군 중 하나 인 경향이 있습니다. 결과적으로 텍스트 편집기에서 utf-8 또는 단일 바이트로 표시되는 유효한 문자가 PHP에 의해 잘못 해석 될 수 있습니다. 따라서 html2text에 유효한 문자를 제공한다고 생각하더라도 그렇지 않을 수 있습니다.

저자는이를 해결하기위한 몇 가지 접근 방식을 제공하고 HTML2Text 버전 2 (DOMDocument 사용)가 UTF-8을 지원한다고 설명합니다.

상업적 사용에 대한 제한 사항에 유의하십시오.


Markdownify는 더 이상 유지되지 않습니다. 온라인 데모는 많은 경고를 표시하고 작동하지 않습니다. 새 버전의 html2text가 내 이메일에서 작동합니다. lkessler에게 늦은 +1.
malcanso

13

신뢰할 수있는 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)));

?>

스트립 태그도 앵커를 제거한다는 것을 잊지 마십시오!
Alix Axel

9

-stdin 및 -dump 옵션과 함께 lynx를 사용하여 다음을 수행 할 수 있습니다.

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

8

이 기능을 테스트 할 수 있습니다.

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

감사합니다. 내 사용에 적합하고 (RSS 피드 용 HTML 변환) 두 가지 추가 사례 (& rsquo; 및 & mdash;)를 추가하기위한 간단한 템플릿을 제공했습니다.
Alan M.

6

간단한 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

길이와 내용이 저품질로 플래그 지정되었습니다. 몰라요. 게시물에 코드를 사용하여 문제를 해결하는 방법에 대한 내용이 포함되어 있거나 주석이어야합니다. 가장 인기있는 답변은 PHP 코드 내에서 솔루션을 호출하는 방법을 보여줍니다.
Bill Bell

그 도서관을 써서 미안 해요. 링크를 클릭하지 않고 예제를보고 싶지 않다면 간단한 예제를 추가했습니다.
Rob

2
미안해 하지마! :-) 나는 그래서 리뷰어로 쓰고 있었다. 링크를 클릭하고 싶지 않은 것이 아닙니다. 표준 이하로 간주되는 것이 필요한 것은 SO 답변입니다. 누가 우연히 당신의 답변에 반대표를 던지는 이유를 모르겠습니다.
Bill Bell

4

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?"`

ENT_QUOTES가있는 html_entity_decode | ENT_XML1은 &#39; htmlspecialchars_decode 와 같은 것을 변환합니다. &amp; html_entity_decode는 같은 것을 변환 '&lt; 하고 strip_tags는 남은 HTML 태그를 제거합니다.


3

Markdownify 는 HTML을이 사이트에서 사용되는 일반 텍스트 형식 시스템 인 Markdown으로 변환합니다.


링크를 처리하는 방법을 제외하고는 좋은 선택입니다. 그러나 고려하고 있다면 온라인 데모를 시도하십시오.
Redzarf 2013-08-13

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

출력
문자열 1
문자열 2
문자열 3
문자열 4
문자열 5


1
그냥 대답을 추가하지 마십시오. 이 대답은 이유 텍스트를 추가하세요
Himanth

2

OP와 동일한 문제가 발생했으며 위의 최상위 답변에서 일부 솔루션을 시도해도 내 시나리오에서 작동하지 않는 것으로 나타났습니다. 끝에서 이유를 확인하십시오.

대신이 유용한 스크립트를 찾았습니다. 혼동을 피하기 위해 html2text_roundcubeGPL에서 사용할 수 있습니다.

실제로 이미 언급 된 스크립트의 업데이트 된 버전입니다 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

방금 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?

3
strip_tags ()는 html에서 '인라인'으로 간주되는 여러 줄에 여러 요소가있는 경우를 처리하지 않고 여러 줄에 표시합니다. 또한 반대의 경우-한 줄에 여러 div 요소가있는 경우 태그를 제거하고 콘텐츠를 연결합니다. 나는 여기에 내 경험을 공유했습니다 : stackoverflow.com/questions/1930297/…
Nikola Petkanski

1

태그를 완전히 제거하고 콘텐츠를 태그 안에 보관하지 않으려면 다음 DOMDocumenttextContent같이 루트 노드 의 를 사용 하고 추출 할 수 있습니다 .

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!

이 접근 방식의 한 가지 장점은 외부 패키지가 필요하지 않다는 것입니다.


1

utf-8의 텍스트의 경우 mb_convert_encoding이 저에게 효과적이었습니다. 오류에 관계없이 모든 것을 처리하려면 "@"를 사용해야합니다.

내가 사용하는 기본 코드는 다음과 같습니다.

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

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

더 발전된 것을 원한다면 노드를 반복적으로 분석 할 수 있지만 공백으로 인해 많은 문제가 발생합니다.

여기서 말하는 내용을 기반으로 변환기를 구현했습니다. 관심이 있으시면 git https://github.com/kranemora/html2text 에서 다운로드 할 수 있습니다.

그것은 당신의 것을 만들기위한 참조로 사용될 수 있습니다

다음과 같이 사용할 수 있습니다.

$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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.