Ошибка кодировки символов, невозможно записать правильный XML из MySQL через PHP - PullRequest
1 голос
/ 10 декабря 2011

Рассматриваемый фид: http://api.inoads.com/snowstorm/feed.xml

Вот код PHP, который я использую для генерации:

<?php

$database =  'xxxx';
$dbconnect = mysql_pconnect('xxxx', 'xxxx', 'xxxx');
mysql_select_db($database, $dbconnect);

$query = "SELECT * FROM the_queue WHERE id LIKE '%'    ORDER BY id DESC LIMIT 25";
$result = mysql_query($query, $dbconnect);

while ($line = mysql_fetch_assoc($result))
        {
            $return[] = $line;
        }

$now = date("D, d M Y H:i:s T");

$output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
            <rss version=\"2.0\">
                <channel>
                    <title>The Queue</title>
                    <link>http://readapp.net</link>
                    <description>A curated reading list.</description>
                    <language>en-us</language>
                    <pubDate>$now</pubDate>
                    <lastBuildDate>$now</lastBuildDate>
            ";

foreach ($return as $line)
{
    $output .= "<item><title>".htmlspecialchars($line['title'])."</title>
    <description>".htmlspecialchars($line['description'])."</description>
                    <link>".htmlspecialchars($line['link'])."</link>
                    <pubDate>".htmlspecialchars($line['pubDate'])."</pubDate>
                </item>";
}
$output .= "</channel></rss>";

$fh = fopen('feed.xml', 'w');
fwrite($fh, $output);
?>

Что может быть причиной ошибки?

Вот ссылка из валидатора каналов: http://validator.w3.org/feed/check.cgi?url=http%3A%2F%2Fapi.inoads.com%2Fsnowstorm%2Ffeed.xml

Ответы [ 5 ]

3 голосов
/ 10 декабря 2011

Вы сказали, что XML-файл - UTF-8, но когда я загружаю его и открываю в текстовом редакторе, он автоматически определяет кодировку windows latin1, и кавычки отображаются отлично.

Если я заставлю свой текстовый редактор использовать UTF-8, он отобразит сообщение об ошибке, поскольку в кодировке UTF-8 есть недопустимые символы.

Следовательно, ваши данные не UTF-8, это латиница 1. Вам нужно выяснить, где именно это происходит. Это может быть один или несколько из:

- это HTML-страница, на которой пользователь печатает содержимое в формате UTF-8?

Если нет, браузер будет отправлять латинские кавычки. Чтобы это исправить, тег first в вашем <head> должен быть:

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  ...
</head>

каждый браузер правильно соблюдает настройку UTF-8 в HTML этой страницы?

Если вы укажете UTF-8, а страница содержит недопустимые символы в этой кодировке, некоторые браузеры могут решить использовать другую кодировку, несмотря на тег <meta>. Как проверить это отличается в каждом браузере.

- это соединение MySQL при вставке в базу данных, настроенную на использование UTF-8?

Вам нужно использовать UTF-8 здесь, иначе MySQL может попытаться преобразовать кодировку для вас, часто повреждая их. Установите кодировку с помощью:

$database =  'xxxx';
$dbconnect = mysql_pconnect('xxxx', 'xxxx', 'xxxx');
mysql_select_db($database, $dbconnect);
mysql_query('SET NAMES utf8', $dbconnect);

таблица MySQL (и отдельный столбец) настроена на использование UTF-8?

Опять же, чтобы MySQL не выполнял свои собственные глючные преобразования, вам нужно убедиться, что он использует UTF-8 для таблицы, а также отдельный комментарий. Сделайте дамп структуры базы данных и проверьте:

CREATE TABLE `the_queue` (
  ...
) ... DEFAULT CHARSET=utf8;

А также убедитесь, что в столбцах нет ничего подобного:

`description` varchar(255) CHARACTER SET latin1,

- это соединение MySQL при чтении базы данных, настроенной на использование UTF-8?

Ваше соединение для чтения также должно быть utf8. Так что дважды проверьте это.

вы делаете что-то в PHP, что не может обработать UTF-8?

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

2 голосов
/ 10 декабря 2011

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

По умолчанию htmlentities использует кодировку latin-1, поэтому она подавляетсяумные кавычки (действительно, все многобайтовые символы), где вы видите знаки вопроса.Одним из исправлений является использование htmlspecialchars для преобразования гораздо более ограниченного набора символов (&, <,>, 'и "). Это все равно преобразует двойные кавычки, потому что, в этом и заключается смыслhtmlspecialchars, если вы не укажете ENT_NOQUOTES в качестве второго аргумента. Другим исправлением является указание набора символов в качестве третьего аргумента (это не исключает использование htmlspecialchars).

Четвертый аргументлибо указывает, следует ли кодировать уже закодированные символы. Будет ли выполняться двойное кодирование, зависит от исходных данных.

$line['description'] = '"Dave, stop. Stop, will you? Stop, Dave. Will you stop, Dave?” ... “Dave, my mind is going,” HAL says, forlornly. “I can feel it. I can feel it.”';

echo "<description>" . htmlspecialchars($line['description'], ENT_NOQUOTES, 'UTF-8', false) . "</description>";

См. также:

1 голос
/ 10 декабря 2011

Здесь есть одна проблема:

$output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
...

Есть строка, содержащая "?>".Это маркер финализации для php.Это даст вам ошибку.

Вы можете избежать этих проблем следующим образом:

$output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?".">
...
0 голосов
/ 10 декабря 2011

Еще одна ошибка, что у вас есть это формат даты.Дата должна быть в формате RFC-822, она должна быть в таком формате: «Ср, 02 октября 2002 08:00:00 EST», а не «Июль / Август 2008».

0 голосов
/ 10 декабря 2011

Проблема в том, что вы держите эту строку с кавычками в базе данных (как я предполагаю).Если это правда, PHP удаляет кавычки (что правильно), потому что не вызывает ошибок (SQL инъекция ex).Таким образом, вы должны удалить кавычки в БД и при создании XML-файла просто добавить их.Это самый простой на мой взгляд.И попробуйте избегать двойных кавычек ". Вы должны использовать одинарные". В парсере двойных PHP дополнительно проверяет, что в.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...