Я нашел несколько сообщений, которые ссылаются на проблему, но никто из них не полностью ее разрешает.
Мне нужна функция, которая будет выводить содержимое, преобразующее все специальные символы в способ htmlentities (), но сохраняющий все теги html.
Я пробовал много разных подходов, но, как я уже упоминал выше, никто из них не работает так, как ожидалось.
Мне было интересно, будет ли способ сделать это с помощью PHP-класса DomDocument.
Я попытался сделать это, используя следующее:
$objDom = new DOMDocument('1.0', 'utf-8'); $objDom->loadhtml($content); return $objDom->savehtml();
который работает, но он также добавляет всю структуру страницы, т. е.
<head><body> etc.
Мне нужно только содержимое переменной $ content, которую нужно преобразовать, и выполнить задание.
Еще одна вещь, которую стоит упомянуть здесь, состоит в том, что в $ content также могут быть некоторые символы, преобразованные в жалобу xhtml – как это происходит от Wysiwyg. Таким образом, он может содержать и т. Д., Которые также должны быть сохранены.
Кто-нибудь знает, как это сделать с помощью DomDocument – возможно, мне нужно использовать другой метод сохранения?
Хорошо – я придумал следующее – не очень, но работает ли эта задача:
$objDom = new DOMDocument('1.0', 'UTF-8'); $objDom->loadHTML($string); $output = $objDom->saveXML($objDom->documentElement); $output = str_replace('<html><body>', '', $output); $output = str_replace('</body></html>', '', $output); $output = str_replace('
', '', $output); return $output;
Любые лучшие идеи будут высоко оценены.
Вы можете использовать get_html_translation_table
и удалить элементы <
и >
:
$trans = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES); unset($trans['<'], $trans['>']); $output = strtr($input, $trans);
get_html_translation_table (HTML_ENTITIES) дает вам таблицу переводов, используемую в htmlentities () как массив. Вы можете удалить <,> и "из массива следующим образом:
<?php $trans = get_html_translation_table(HTML_ENTITIES); unset($trans["\""], $trans["<"], $trans[">"]); $str = "Hallo <strong>& Frau</strong> & Krämer"; $encoded = strtr($str, $trans); echo $encoded; ?>
Позвольте мне начать с того, что, на мой взгляд, то, что вы пытаетесь сделать, является фундаментально неправильным. Что делать, если кто-то хочет напечатать знак меньше, чем? Лично я вижу htmlentities()
как способ убедиться, что пользователи не могут ввести свой собственный HTML-код.
Если вам нужно, чтобы пользователи могли стилизовать текст, для этого есть много решений (например, посмотрите TinyMCE или Markdown ).
Если вы должны разрешить пользователям вводить теги HTML, и вы должны предположить, что они не знают, как использовать объекты, вот простая функция, которая работает:
function my_htmlentities ($str) { // We'll append everything to this. $result = ''; // Continue while there are HTML tags. while (($lt = strpos($str, '<')) !== false) { // Run `htmlentities` on everything before the tag, and pop it // off the original string. $result .= htmlentities(substr($str, 0, $lt)); $str = substr($str, $lt); // We want to continue until we reach the end of the tag. I know // these loops are bad form. Sorry. I still think in F77 :p while (true) { // Find the closing tag as well as quotes. $gt = strpos($str, '>'); $quot = strpos($str, '"'); // If there is no closing bracket, append the rest of the tag // as plaintext and exit. if ($gt === false) return $result . $str; // If there is a quote before the closing bracket, take care // of it. if ($quot !== false && $quot < $gt) { // Grab everything before the quote. $result .= substr($str, 0, $quot+1); $str = substr($str, $quot+1); // Find the closing quote (if there is none, append and // exit). if (($quot = strpos($str, '"')) === false) return $result . $str; // Grab the inside of the quote. $result .= substr($str, 0, $quot+1); $str = substr($str, $quot+1); // Start over as if we were at the beginning of the tag. continue; } // We just have the closing bracket to deal with. Deal. $result .= substr($str, 0, $gt+1); $str = substr($str, $gt+1); break; } } // There are no more tags, so we can run `htmlentities()` on the // rest of the string. return $result . htmlentities($str); // Alternatively, if you want users to be able to enter their own // entities as well, you'll have to use this last line instead: return str_replace('&', '&', $result . htmlentities($str)); }
Но, пожалуйста, позвольте мне повторить: это крайне небезопасно! Я дам вам пользу от сомнений в том, что вы знаете, чего хотите, но я не думаю, что вам (или кому-то) это нужно.
Хорошо – после многих исследований я придумал окончательный вариант, который, кажется, был именно тем, что мне нужно.
Я использовал HTMLPurifier и отфильтровал свой контент, используя следующее:
require_once('HTMLPurifier/HTMLPurifier.auto.php'); $config = HTMLPurifier_Config::createDefault(); $config->set('HTML.Doctype', 'XHTML 1.0 Transitional'); $objPurifier = new HTMLPurifier($config); return $objPurifier->purify($string);
Я надеюсь, что кто-то еще найдет это полезным.