PHP: отображение первых 500 символов HTML - PullRequest
6 голосов
/ 19 апреля 2011

У меня огромный код HTML в переменной PHP, такой как:

$html_code = '<div class="contianer" style="text-align:center;">The Sameple text.</div><br><span>Another sample text.</span>....';

Я хочу отображать только первые 500 символов этого кода. Это число символов должно учитывать текст в тегах HTML и исключать теги и атрибуты HTMl при измерении длины. но при обрезке кода это не должно влиять на структуру DOM HTML-кода.

Есть ли учебные или рабочие примеры?

Ответы [ 4 ]

4 голосов
/ 19 апреля 2011

Если это текст, который вы хотите, вы можете сделать это с помощью следующего

substr(strip_tags($html_code),0,500);
3 голосов
/ 19 апреля 2011

Оооо ... Я знаю это, я не могу получить это точно с моей головы, но вы хотите загрузить текст, который вы получили в качестве ДОМОКУМЕНТА

http://www.php.net/manual/en/class.domdocument.php

затем захватывает текст со всего узла документа (как DOMnode http://www.php.net/manual/en/class.domnode.php)

Это будет не совсем правильно, но, надеюсь, это выведет вас на правильный путь. Попробуйте что-то вроде:

 $html_code = '<div class="contianer" style="text-align:center;">The Sameple text.</div><br><span>Another sample text.</span>....';
 $dom = new DOMDocument();
 $dom->loadHTML($html_code);
 $text_to_strip = $dom->textContent;
 $stripped = mb_substr($text_to_strip,0,500);
 echo "$stripped";  // The Sameple text.Another sample text.....

edit ок ... это должно работать. только что протестировано локально

edit2

Теперь, когда я понимаю, вы хотите сохранить теги, но ограничить текст, давайте посмотрим. Вы захотите зациклить контент, пока не получите 500 символов. Возможно, мне понадобится несколько правок и пропусков, чтобы я понял, как надо, но, надеюсь, я смогу помочь. (извините, я не могу уделять все внимание)

Первый случай, когда текст меньше 500 символов. Не о чем беспокоиться. Начиная с приведенного выше кода, мы можем сделать следующее.

  if (strlen($stripped) > 500) {
       // this is where we do our work.

       $characters_so_far = 0;
       foreach ($dom->child_nodes as $ChildNode) {

          // should check if $ChildNode->hasChildNodes();
          // probably put some of this stuff into a function
          $characters_in_next_node += str_len($ChildNode->textcontent);
          if ($characters_so_far+$characters_in_next_node > 500) { 
              // remove the node 
              // try using 
              // $ChildNode->parentNode->removeChild($ChildNode);
          } 
          $characters_so_far += $characters_in_next_node
       }
       // 
       $final_out = $dom->saveHTML();
  } else {
        $final_out = $html_code;
  }
2 голосов
/ 19 апреля 2011

Я вставляю ниже класса php. Я написал давно назад, но я знаю, что это работает.это не совсем то, что вам нужно, так как он имеет дело со словами вместо количества символов, но я считаю, что это довольно близко, и кто-то может найти это полезным.

  class HtmlWordManipulator
  {
    var $stack = array();

    function truncate($text, $num=50) 
    { 
      if (preg_match_all('/\s+/', $text, $junk) <= $num) return $text; 
      $text = preg_replace_callback('/(<\/?[^>]+\s+[^>]*>)/','_truncateProtect', $text); 
      $words = 0; 
      $out = array();
      $text = str_replace('<',' <',str_replace('>','> ',$text));
      $toks = preg_split('/\s+/', $text);
      foreach ($toks as $tok) 
      { 
        if (preg_match_all('/<(\/?[^\x01>]+)([^>]*)>/',$tok,$matches,PREG_SET_ORDER))  
          foreach ($matches as $tag) $this->_recordTag($tag[1], $tag[2]);  
        $out[] = trim($tok);
        if (! preg_match('/^(<[^>]+>)+$/', $tok))
        {
          if (!strpos($tok,'=') && !strpos($tok,'<') && strlen(trim(strip_tags($tok))) > 0) 
          {
           ++$words; 
          }
          else
          {                 
            /*
            echo '<hr />';
            echo htmlentities('failed: '.$tok).'<br /)>'; 
            echo htmlentities('has equals: '.strpos($tok,'=')).'<br />';
            echo htmlentities('has greater than: '.strpos($tok,'<')).'<br />';
            echo htmlentities('strip tags: '.strip_tags($tok)).'<br />';
            echo str_word_count($text);
            */
          } 
        }
        if ($words > $num) break; 
      } 
      $truncate = $this->_truncateRestore(implode(' ', $out));   
      return $truncate; 
    }

    function restoreTags($text)
    {
      foreach ($this->stack as $tag) $text .= "</$tag>";
      return $text;
    } 

    private function _truncateProtect($match) 
    { 
      return preg_replace('/\s/', "\x01", $match[0]); 
    } 

    private function _truncateRestore($strings) 
    { 
      return preg_replace('/\x01/', ' ', $strings); 
    }

    private function _recordTag($tag, $args) 
    { 
      // XHTML 
      if (strlen($args) and $args[strlen($args) - 1] == '/') return; 
      else if ($tag[0] == '/') 
      { 
        $tag = substr($tag, 1); 
        for ($i=count($this->stack) -1; $i >= 0; $i--) { 
         if ($this->stack[$i] == $tag) { 
           array_splice($this->stack, $i, 1); 
           return; 
         } 
        } 
        return; 
      } 
      else if (in_array($tag, array('p', 'li', 'ul', 'ol', 'div', 'span', 'a'))) 
        $this->stack[] = $tag;  
      else return;
    } 
  }

усечение - это то, что вы хотите, и вы передаете ему html и количество слов, которое хотите, чтобы оно было урезано.он игнорирует HTML при подсчете слов, но затем переворачивает все в HTML, даже закрывая конечные теги из-за усечения.

пожалуйста, не судите меня по полному отсутствию принципов.я был молодым и глупым.

edit:

, поэтому получается, что использование более похоже на это:

$content = $manipulator->restoreTags($manipulator->truncate($myHtml,$numOfWords));

глупое дизайнерское решение.позволил мне вводить html внутри незакрытых тегов.

1 голос
/ 19 апреля 2011

Я не собираюсь кодировать реальное решение, но если кто-то захочет, вот что я бы сделал (в псевдо-PHP):

$html_code = '<div class="contianer" style="text-align:center;">The Sameple text.</div><br><span>Another sample text.</span>....';
$aggregate = '';

$document = XMLParser($html_code);

foreach ($document->getElementsByTagName('*') as $element) {
  $aggregate .= $element->text(); // This is the text, not HTML. It doesn't
                                  // include the children, only the text
                                  // directly in the tag.
}
...