Оставьте существующие объекты HTML как есть, но преобразуйте двойные и одинарные кавычки

Я использую PHP-код для создания тега мета-описания, например:

<meta name="description" content="<?php
echo $this->utf->clean_string(word_limiter(strip_tags(trim($paperResult['file_content'])),27));
?>


Вот пример вывода метаописания:

<meta name="description" content="blah blah &#182; &#8230; blah blah "words in quotation marks" blah blah "more words in quotation marks" blah blah" />

Два объекта HTML в мета-описании этого примера представляют собой знак абзаца (&#182;), за которым следует многоточие (&#8230;). Они уже находятся в форме объекта HTML в исходном тексте, поэтому я хочу, чтобы они оставались неизменными. Проблема в том, что мне также нужны кавычки в описании для преобразования в &quot;, чтобы предотвратить нарушение метатега. Каждая комбинация/конфигурация, которую я пробую, либо не работает, либо ломает мой сайт, потому что я неправильно понимаю код. Например, когда я пробую следующий код, кавычки преобразуются в свой HTML-объект, как хотелось бы, но символы абзаца и многоточия ломаются, потому что символ амперсанда в начале существующих объектов HTML преобразуется в &amp;. Это оставляет меня со сломанным &#182; (&amp;#182;) и сломанным &#8230; (&amp;#8230;):

 echo $this->utf->clean_string(word_limiter(htmlspecialchars(strip_tags(trim($paperResult['file_content']))),27));

Я пытался — буквально несколько дней — понять это. Я много искал в Stack Overflow, но безрезультатно. Мне просто нужно, чтобы существующие объекты HTML оставались неизменными, а кавычки были преобразованы в их объекты HTML (&quot;). Я изучил параметр ENT_QUOTES и знаю, что решение, вероятно, существует там, но я не могу понять, как включить это в мою конкретную строку кода. Я надеюсь, что вы, гуру PHP, сжалитесь над этой измученной душой! Я был бы очень признателен за вашу помощь.

Спасибо!


person Jason    schedule 16.10.2018    source источник
comment
Как именно выглядит $paperResult['file_content']?   -  person miken32    schedule 16.10.2018
comment
Спасибо за вопрос! Это зависит от исходного файла, которых более 200 000. Он выводит первые x слов (в настоящее время установлено значение 27) в верхней части файла. Во многих случаях. в этих первых 27 словах есть как существующие объекты HTML, так и кавычки.   -  person Jason    schedule 16.10.2018
comment
Пожалуйста, отредактируйте свой вопрос, чтобы привести несколько примеров   -  person miken32    schedule 16.10.2018
comment
Если это просто содержимое атрибута содержимого, вы можете использовать echo htmlentities($str, ENT_QUOTES, "UTF-8", false); с последним аргументом (двойное кодирование) как false и ENT_QUOTES для преобразования кавычек. Если это весь тег, это немного сложнее.   -  person ArtisticPhoenix    schedule 16.10.2018
comment
Вы видели пример, который я уже приводил? Я не уверен, что еще предоставить. Вывод всегда 27 слов. Сами по себе отдельные слова значения не имеют. Всякий раз, когда среди этих 27 слов оказывается кавычка (то есть символ двойной кавычки), метатег разрывается, потому что кавычка конфликтует с кавычкой, открывающей тег. Надеюсь, это поможет. :)   -  person Jason    schedule 16.10.2018
comment
@ArtisticPhoenix, скорее всего, вы правы. На самом деле я пытался использовать это точное решение, но я просто не могу правильно включить этот новый код в мою существующую строку кода, не нарушая мой сайт. Я балуюсь PHP, когда мне нужно (как в этой ситуации), но я, конечно, не такой эксперт, как вы, ребята.   -  person Jason    schedule 16.10.2018
comment
Когда это произойдет, разбейте шаги на части, а затем последовательно выполняйте каждую операцию и проверяйте результат. Это может быть просто порядок, в котором вы делаете что-то. Например, если вы strip_tags после использования htmlentities, Песочница имеет значение. Я должен упомянуть, что если у вас есть весь метатег, то теги полосы удалят его (и атрибут содержимого).   -  person ArtisticPhoenix    schedule 16.10.2018
comment
Что подводит меня к тому, что он выводит, если что-нибудь?   -  person ArtisticPhoenix    schedule 16.10.2018
comment
Вы не предоставили никакого примера ввода, вы показываете вывод только после того, как на нем были запущены многие ваши функции.   -  person miken32    schedule 16.10.2018


Ответы (2)


Если это содержимое атрибута "content", вы можете сделать это

$str = 'blah blah &#182; &#8230; blah blah "words in quotation marks" blah blah "more words in quotation marks" blah blah';
echo htmlentities($str, ENT_QUOTES, "UTF-8", false);

Вывод

blah blah &#182; &#8230; blah blah &quot;words in quotation marks&quot; blah blah &quot;more words in quotation marks&quot; blah blah

Песочница

Ключевым моментом здесь является 4-й аргумент

строка htmlentities ( строка $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, строка $encoding = ini_get("default_charset") [, bool $double_encode = TRUE ]]] )

Конкретно

double_encode Когда double_encode отключен, PHP не будет кодировать существующие объекты html. По умолчанию конвертировать все.

Таким образом, он не будет дважды кодировать амперсанд.

htmlspecialchars также имеет аргумент двойного кодирования.

htmlspecialchars (string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = ini_get("default_charset") [, bool $double_encode = TRUE ]]] )

$str = 'blah blah &#182; &#8230; blah blah "words in quotation marks" blah blah "more words in quotation marks" blah blah';
echo htmlspecialchars($str, ENT_QUOTES, "UTF-8", false);

Вывод

blah blah &#182; &#8230; blah blah &quot;words in quotation marks&quot; blah blah &quot;more words in quotation marks&quot; blah blah

Песочница

Если это весь тег, то вам придется вытащить содержимое и изменить его, а затем заменить его, чтобы сохранить < и >, но в вопросе не ясно, так ли это.

PS нет большой разницы между htmlspecialchars и htmlentities, в основном это связано с é accute и другими подобными вещами, htmlentities их тоже кодирует, если я правильно помню.

ОБНОВЛЕНИЕ

Мне нужно, чтобы решение было включено в мой конкретный формат кода PHP (т. е. в одну строку PHP, которая поддерживает мои существующие функции/функциональность), как miken32 блестяще сделал выше

Чтобы поместить это в свой код,

<meta name="description" content="<?=htmlspecialchars(word_limiter(trim($paperResult['file_content']),27),ENT_QUOTES,"UTF-8",false);?>"/>

ОБНОВЛЕНИЕ 2

С preg_replace('/[\r\n]+/', ' ', $string) удаляет \r\n или \n один или несколько раз +. Но, может быть, лучше сделать так preg_replace(['/[\r\n]+/', '/\s+/'], ' ', $string). Что также убрало бы бег по пробелам.

 <meta name="description" content="<?=htmlspecialchars(word_limiter(preg_replace('/[\r\n]+/', ' ', trim($paperResult['file_content'])),27),ENT_QUOTES,"UTF-8",false);?>"/>

По сути, это все, что делает текст короче, что вы, вероятно, захотите сделать до word_limiter (что бы это ни было). И все, что делает его длиннее, например, изменение " на &quote;, которое вы, вероятно, захотите сделать после (возможно). Просто мне это кажется более логичным.

Ваше здоровье!

person ArtisticPhoenix    schedule 16.10.2018
comment
ArtisticPhoenix, я очень ценю ваше время и опыт! Спасибо! Однако в этом конкретном случае мне нужно, чтобы решение было включено в мой конкретный формат PHP-кода (то есть в одну строку PHP, которая поддерживает мои существующие функции/функциональность), как miken32 блестяще сделал выше. В идеальном мире, однако, я все же хотел бы иметь решение, которое оставляет все существующие объекты HTML нетронутыми (т. е. не преобразует их в соответствующие им символы) и одновременно преобразует кавычки (т. е. , двойные кавычки) к их эквиваленту объекта HTML (&quot;). - person Jason; 16.10.2018
comment
Было бы просто <meta name="description" content="<?=htmlspecialchars(word_limiter($paperResult['file_content'], 27),ENT_QUOTES,"UTF-8", false);?>"/> - person ArtisticPhoenix; 17.10.2018
comment
УДИВИТЕЛЬНО, ArtisticPhoenix! Это отлично работает! Большое спасибо! И еще: можете ли вы опубликовать вторую версию своего кода, которая включает функцию preg_replace, которая заменяет 1 или более разрывов строк одним пробелом? - person Jason; 17.10.2018
comment
Это как бы отдельный вопрос, preg_replace('/[\r\n]+/', ' ', $string) - person ArtisticPhoenix; 17.10.2018

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

<meta name="description" content="<?=htmlspecialchars(html_entity_decode(word_limiter($paperResult['file_content'], 27)))?>"/>

Поэтому ограничьте количество слов, превратите любые объекты в символы, а затем снова превратите любые специальные символы в объекты. Нет необходимости удалять теги и тому подобное для безопасности, поскольку htmlspecialchars гарантирует, что любой вывод будет безопасным для включения в HTML.

person miken32    schedule 16.10.2018
comment
Вы, сэр, правите миром! Вы взяли мою существующую структуру кода и воплотили ее в жизнь! Хотя моей целью было оставить все существующие объекты HTML нетронутыми при преобразовании каждой кавычки в &quot;, ваше решение помогает! По крайней мере, я думаю, что да. Я не решаюсь объявить о полной победе, потому что не уверен, что специальные символы (такие как ¶ и …) будут корректно отображаться в поисковой выдаче Google и на всех устройствах. Я всегда считал, что использование сущности HTML более универсально и безопасно. Любые знания/мнения по этому поводу? - person Jason; 16.10.2018
comment
В наши дни все поддерживает Unicode, если ваш сервер правильно настроен, нет необходимости в объектах, кроме тех, что обрабатывает htmlspecialchars(), а именно ‹, ›, и &. Те, которые экранируются, являются требованием для HTML и XML, поэтому их нельзя избежать. - person miken32; 16.10.2018
comment
Если вы хотите превратить каждый символ в сущность, вы можете использовать htmlentities вместо htmlspecialchars. - person miken32; 17.10.2018
comment
Я пробовал это изначально, но он сломал существующие объекты HTML, преобразовав начальный амперсанд каждого существующего объекта из & в &amp;. - person Jason; 17.10.2018
comment
Нет, потому что вы сначала избавились от них с помощью html_decode_entities - person miken32; 17.10.2018