htmlentities в PHP, но сохраняющий теги HTML

При создании кластерного индекса он влияет на способ, которым данные физически заказаны на диске. Лучше добавить индекс после факта и позволить механизму базы данных переупорядочить строки, когда это знает, как данные распределяются.

, Например, скажем, необходимо было создать кирпичную стену с пронумерованными кирпичами так, чтобы те, которые имеют самое большое количество, были у основания стены. Это была бы трудная задача, если бы Вам просто вручили кирпичи в произвольном порядке, по одному то - Вы не знали бы, какие кирпичи собирались оказаться самым высоким, пронумерованным, и необходимо будет разъединить стену и восстановить ее много раз. Было бы намного легче справиться с той задачей, если бы Вы имели все кирпичи, выстроенные в линию перед Вами, и могли бы организовать Вашу работу.

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

55
задан fidoboy 1 September 2009 в 11:19
поделиться

5 ответов

Вы можете получить список соответствий character => entity, используемой htmlentities , с помощью функции get_html_translation_table ;рассмотрите этот код:

$list = get_html_translation_table(HTML_ENTITIES);
var_dump($list);

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

Это даст вам что-то вроде это:

array
  ' ' => string ' ' (length=6)
  '¡' => string '¡' (length=7)
  '¢' => string '¢' (length=6)
  '£' => string '£' (length=7)
  '¤' => string '¤' (length=8)
  ....
  ....
  ....
  'ÿ' => string 'ÿ' (length=6)
  '"' => string '"' (length=6)
  '<' => string '&lt;' (length=4)
  '>' => string '&gt;' (length=4)
  '&' => string '&amp;' (length=5)

Теперь удалите соответствия, которые вам не нужны:

unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

В вашем списке теперь есть все символы соответствия => сущности, используемые htmlentites, за исключением нескольких символов, которые вы не хотите кодировать.

] И теперь вам просто нужно извлечь список ключей и значений:

$search = array_keys($list);
$values = array_values($list);

И, наконец, вы можете использовать str_replace для замены:

$str_in = '<p><font style="color:#FF0000">Camión español</font></p>';
$str_out = str_replace($search, $values, $str_in);
var_dump($str_out);

И вы получите:

string '<p><font style="color:#FF0000">Cami&Atilde;&sup3;n espa&Atilde;&plusmn;ol</font></p>' (length=84)

Что похоже на то, что вы хотели; - )


Редактировать: ну, за исключением проблемы с кодировкой (черт UTF-8, я полагаю - я пытаюсь найти решение для этого и буду редактировать снова)

Второе редактирование через пару минут: это кажется ты 'Вам нужно будет использовать utf8_encode в списке $ search перед вызовом str_replace : - (

Что означает использование чего-то вроде этого:

$search = array_map('utf8_encode', $search);

Между вызов array_keys и вызов str_replace .

И на этот раз вы действительно должны получить то, что хотели:

string '<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>' (length=70)


И вот полный фрагмент кода:

$list = get_html_translation_table(HTML_ENTITIES);
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

$search = array_keys($list);
$values = array_values($list);
$search = array_map('utf8_encode', $search);

$str_in = '<p><font style="color:#FF0000">Camión español</font></p>';
$str_out = str_replace($search, $values, $str_in);
var_dump($str_in, $str_out);

И полный вывод:

string '<p><font style="color:#FF0000">Camión español</font></p>' (length=58)
string '<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>' (length=70)

На этот раз все должно быть нормально ^^все должно быть хорошо ^^все должно быть хорошо ^^
Это не совсем умещается в одной строке, возможно, это не самое оптимизированное решение; но он должен работать нормально и имеет то преимущество, что вы можете добавлять / удалять любой символ соответствия => сущность, которая вам нужна или нет.

Удачи!

65
ответ дан 7 November 2019 в 07:19
поделиться

Может быть не очень эффективным, но работает

$sample = '<p><font style="color:#FF0000">Camión español</font></p>';

echo htmlspecialchars_decode(
    htmlentities($sample, ENT_NOQUOTES, 'UTF-8', false)
  , ENT_NOQUOTES
);
18
ответ дан 7 November 2019 в 07:19
поделиться

Ни одно решение, кроме парсера, не будет правильным для всех случаев. Ваш хороший случай:

<p><font style="color:#FF0000">Camión español</font></p>

, но хотите ли вы также поддержать:

<p><font>true if 5 < a && name == "joe"</font></p>

, где вы хотите, чтобы это выглядело как:

<p><font>true if 5 &lt; a &amp;&amp; name == &quot;joe&quot;</font></p>

Вопрос: Можете ли вы выполнить кодирование ДО того, как вы создадите HTML. Другими словами, можно сделать что-то вроде:

"<p><font>" + htmlentities(inner) + "</font></p>"

Вы избавите себя от горя, если сможете это сделать. Если вы не можете этого сделать, вам понадобится способ пропустить кодирование <,> и "(как описано выше) или просто закодировать все это, а затем отменить его (например, replace ('& lt;', '<') )

5
ответ дан 7 November 2019 в 07:19
поделиться

Вот функция, которую я только что написал и которая решает эту проблему очень элегантным способом:

Сначала из строки будут извлечены HTML-теги, затем htmlentities() будет выполняться на каждой оставшейся подстроке и после этого оригинальные HTML-теги будут вставлены на их старую позицию, что приведет к отсутствию чередования HTML-тегов. :-)

Веселитесь:

function htmlentitiesOutsideHTMLTags ($htmlText)
{
    $matches = Array();
    $sep = '###HTMLTAG###';

    preg_match_all("@<[^>]*>@", $htmlText, $matches);   
    $tmp = preg_replace("@(<[^>]*>)@", $sep, $htmlText);
    $tmp = explode($sep, $tmp);

    for ($i=0; $i<count($tmp); $i++)
        $tmp[$i] = htmlentities($tmp[$i]);

    $tmp = join($sep, $tmp);

    for ($i=0; $i<count($matches[0]); $i++)
        $tmp = preg_replace("@$sep@", $matches[0][$i], $tmp, 1);

    return $tmp;
}
3
ответ дан 7 November 2019 в 07:19
поделиться

Это оптимизированная версия принятого ответа.

$list = get_html_translation_table(HTML_ENTITIES);
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

$string = strtr($string, $list);
7
ответ дан 7 November 2019 в 07:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: