htmlspecialchars utf-8 возвращает пустую строку

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

<description><![CDATA[<?=htmlspecialchars(utf8_substr($row['texto'], 0, 100), ENT_QUOTES, 'utf-8') ?>...]]></description>

Некоторые записи отображаются нормально, а другие не возвращают никакого текста... Есть идеи, что может быть не так?

Это весь код:

<?php

require('php/config.php');
require('php/db.php');
require('php/utils.php');

header("Content-type: application/xml");

$db = new TSQL('SELECT * FROM entradas WHERE estado = 1 ORDER BY fecha DESC LIMIT 20');
if ( $db->executeQuery() ) {

?><?='<?xml version="1.0" encoding="utf-8" ?>' ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Tu Secreto</title>
        <link>http://www.tusecreto.com.ar/</link>
        <description>TuSecreto / No se lo cuentes a nadie, contaselo a todos</description>
        <language>es-ar</language>
        <copyright>TuSecreto (C) 2005-<?php print strftime("%Y", time()); ?></copyright>
        <lastBuildDate><?=strftime("%a, %d %b %Y %H:%M:%S ", $row['fecha']) ?></lastBuildDate>
        <atom:link href="http://www.tusecreto.com.ar/rss.php" rel="self" type="application/rss+xml" />
        <docs>http://www.tusecreto.com.ar/rss.php</docs>
        <generator>TuSecreto RSS Generator v1.0</generator>
        <ttl>10</ttl>
        <? while ($row = $db->getRow(MYSQL_ASSOC)) { ?>
        <item>
            <title><?=($row['sexo'] == MUJER)?'Mujer':'Hombre' ?> | <?=$row['edad'] ?> <?="A\xC3\xB1os" ?></title>
            <description><![CDATA[<?=htmlspecialchars(utf8_substr($row['texto'], 0, 100), ENT_QUOTES, 'utf-8') ?>...]]></description>
            <link>http://www.tusecreto.com.ar/<?=$row['id'] ?></link>
            <guid isPermaLink="true">http://www.tusecreto.com.ar/<?=$row['id'] ?></guid>
            <pubDate><?=strftime("%a, %d %b %Y %H:%M:%S ", $row['fecha']) ?></pubDate>
        </item>
        <?php } ?>
    </channel>
</rss>

Это один результат, который возвращает пустую строку:

una vez en el colectivo (sentada en el asiento Individual) me dormí y cuando doblo me caí en el pasillo re mal! se mataron de la risa todos!! хаста эль коллективеро! Будьте здоровы с Facebook. Э.П.


person Santiago    schedule 18.06.2012    source источник
comment
Приведите пример некоторых из них, которые возвращают пустую строку.   -  person Jonathan M    schedule 18.06.2012
comment
Как определяется utf8_substr?   -  person Gumbo    schedule 18.06.2012
comment
Я обновил пост со всем кодом и одним результатом... Может быть, это из-за акцентированных символов? общежитие. Испанский...   -  person Santiago    schedule 18.06.2012


Ответы (2)


В вашем коде используется htmlspecialchars($string, ENT_QUOTES, 'utf-8'). Цитата из справочной страницы

Если входная строка содержит недопустимую последовательность единиц кода в данной кодировке, будет возвращена пустая строка, если только не установлены флаги ENT_IGNORE или ENT_SUBSTITUTE.

Используйте, например. htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, 'utf-8') в качестве быстрого обходного пути.

Если неверный ввод действительно является вашей проблемой, конечно, вы должны сначала выяснить, почему utf8_substr($row['texto'], 0, 100) не возвращает допустимую строку UTF-8.

person xebeche    schedule 27.10.2012
comment
(1) По умолчанию не ENT_QUOTES, а ENT_COMPAT. (2) Что документ говорит о ENT_IGNORE: молча отбрасывать недопустимые последовательности единиц кода вместо возврата пустой строки. Использование этого флага не рекомендуется, так как это » может иметь последствия для безопасности. (3) ENT_SUBSTITURE доступен только начиная с PHP 5.4.0 - person jeromej; 19.04.2014
comment
Определенно не игнорируйте эту ошибку с ENT_IGNORE, так как это имеет последствия для безопасности, согласно документам. - person Leo Galleguillos; 07.06.2016

Это все еще не решено, и я недавно нашел решение проблемы, похожей на эту: ненормальные символы заставляли функцию печатать пустую строку. Поэтому я намерен разместить свой вклад.

В области флагов добавьте | ENT_SUBSTITUTE и измените тип кодировки на cp1252. Флаг ENT_SUBSTITUTE гарантирует замену любых нераспознанных символов вместо создания пустой строки. Однако тип кодировки cp1252 специфичен для Windows, и я предлагаю посмотреть другие типы на странице руководства, если он не работает (https://www.php.net/manual/en/function.htmlspecialchars.php). (Я предположил, что эта кодировка работает для меня, потому что мой сервер работает на Windows IIS)

РЕДАКТИРОВАТЬ: у вас также есть возможность удалить тип кодировки в файлах XML, и PHP будет работать с ним нормально.

person Jamesthe1    schedule 03.02.2020