【问题标题】:how to handle all special characters in HTML/php form that outputs to XML如何处理输出到 XML 的 HTML/php 形式的所有特殊字符
【发布时间】:2011-12-24 22:09:54
【问题描述】:

我有一个小 php/mysql 应用程序,我将它放在一起,它采用输入表单并将其存储在 MySQL 数据库中,并将数据作为 XML 输出以供无线电播放硬件设备使用。

问题在于和号和其他字符。用户正在获取各种广播电台的描述,以及流媒体 URL 或播放列表 URL,并将它们粘贴到表单中。一些广播电台位于非英语国家(主要是法语)。我需要知道如何预处理这些字段,以便生成的 XML 不会损坏,这会破坏外部硬件应用程序。

我假设这应该进入提交表单时调用的 php。我很确定应该使用 htmlspecialchars 函数,但我不确定最好的方法,因为我已经从各种来源一起破解了这个:

更新:这是我当前的输出代码,其中包含一些清理 & 符号的正则表达式。

<?
include("HLN/manager/connect.php");

$query = "SELECT * FROM hln_stations ORDER BY orderid ASC";
$result = mysql_query($query);

$num = mysql_num_rows ($result);
mysql_close();

$xml = new XMLWriter();

$xml->openURI("php://output");
$xml->startDocument();
header('Content-type: text/xml');
$xml->setIndent(true);

$xml->startElement('channels');

while ($row = mysql_fetch_assoc($result)) {

  $xml->startElement("channel");
     $xml->startElement("title");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['station_title']));
     $xml->endElement();
     $xml->startElement("descriptionline1");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['station_display_name']));
     $xml->endElement();

     $xml->startElement("descriptionline2");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['station_subtitle']));
     $xml->endElement();

     $xml->startElement("description");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['station_detailed_description']));
     $xml->endElement();

     $xml->startElement("sdimage");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['sdtv_thumbnail_graphic_url']));
     $xml->endElement();

     $xml->startElement("hdimage");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['hdtv_thumbnail_graphic_url']));
     $xml->endElement();

     $xml->startElement("uri");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['stream_url_or_playlist_url']));
     $xml->endElement();

     $xml->startElement("linktype");
          $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;',$row['link_type']));
     $xml->endElement();

 $xml->endElement();
}

$xml->endElement();


$xml->flush();

?>

但我仍然需要解决出现的法语字符集问题。例如,如何将 é 字符替换为不会引起问题的字符?

【问题讨论】:

标签: php html xml


【解决方案1】:

如果你想真正“清理法语字符”(删除)

这样做怎么样 (iconv) ?

iconv('utf8', 'ascii//TRANSLIT', $text);

【讨论】:

  • 这仍然给出:XML Parsing Error: not well-formed in Firefox,虽然它不是目的地,但告诉我它不能在设备上工作。
  • alphablender:如果您的输入是 UTF8,这应该删除所有变音符号。也许输入不是UTF8而是iso8859-1?尝试检测原始编码(使用iconv),然后将其转换为ASCII,应该可以工作
【解决方案2】:

您在 Firefox 中出现错误,表示格式不正确,因为检测到的字符集与您输出的字符集不匹配。我尝试了各种字符集组合,并且可以重现该问题。

您必须明确指定您的字符集,例如:

header('Content-type: text/xml; charset=UTF-8');
$xml = new XMLWriter();
$xml->openURI("php://output");
$xml->startDocument("1.0", "UTF-8");

如果在内容类型和 XML 中将字符集指定为 UTF-8 会导致错误,这意味着您的输入不是有效的 UTF-8,请尝试改用 ISO-8859-15,或重新编码您的输入。

您必须为网站的每个页面添加内容类型字符集标题,包括输入数据的表单,否则您的特殊字符可能会被弄乱。此外,您必须连接到 mysql,指定要用于连接的字符集,并且该字符集应与表的字符集和排序规则相匹配。

假设您使用的是 UTF-8,请使用 PHPMyAdmin 和 UTF-8 连接查看您的数据库,如果您无法很好地看到您的特殊字符,则意味着您做错了。

对于设备,如果你说它只能显示 ASCII 字符,它是在你提供 UTF-8 输入时为你做转换,还是你必须给实体如:

Ch&#xE9;rie 

如果这两个选项不起作用,您可能需要转换为 ASCII,例如“Cherie”...但这是最后的手段。


不使用数据库的概念验证代码:

<?php

header('Content-type: text/xml; charset=UTF-8');

$radioArr = array(
   array("Chérie FM @Work", "http://www.listenlive.eu/cheriefm_atwork.m3u?p&test"), 
   array("Hélène FM", "http://broadcast.infomaniak.ch/helenefm-high.mp3.m3u")
);
$xml = new XMLWriter();
$xml->openURI("php://output");
$xml->startDocument("1.0", "UTF-8");
$xml->setIndent(true);
$xml->startElement('channels');
foreach ($radioArr AS $radio) {
     $xml->startElement("channel");

     $xml->startElement("title");
     $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;', $radio[0]));
     $xml->endElement();

     $xml->startElement("uri");
     $xml->writeRaw(preg_replace('/&(?![A-Za-z0-9#]{1,7};)/','&amp;', $radio[1]));
     $xml->endElement();

     $xml->endElement(); //end channel
}

$xml->endElement();
$xml->flush();

?>

【讨论】:

  • 设备可以接受 XML 格式的 utf-8,但只能在屏幕上显示 ASCII 字符。这是导致问题的字符串:Nous vous souhaitons la plus cordiale bienvenue sur le site de la Radio Shalom Fm。 Nous sommes une station évangélique et nous sommes ouverts 24/24。 Nous vous offrons une programmation diversifiee axée sur trois grands fundements évangéliques à savoir: la prière, l'enseignement et l'évangélisation
  • 好吧,ASCII 是 0-127 字符范围,不包括任何重音字母,所以如果它真的只能接受 ASCII,那么你唯一能做的就是将重音字母转换为基本对应物。您确定吗?使用 unicode 怎么样?它可以与这个“Chérie”一起使用吗?
  • 我试过你的字符串,至少在 Firefox 中没有问题。
  • 所有表单上的内容类型为:content="text/html; charset=iso-8859-1。PhpMYAdmin 是 UTF-8 连接,如果我将其粘贴到字段中,é 会显示在那里,并且,即使添加了您建议的 xml 标头和 startdocument,如果我将该字符放入表单中的字段中,我仍然会收到错误消息。
  • "所有表单的内容类型为:content="text/html;字符集=iso-8859-1。 PhpMYAdmin 是 UTF-8 连接,如果我将其粘贴到字段中,é 会显示在那里" --> 这证实了我的担忧,您的数据库数据以 UTF-8 保存,但您从用户那里获得了 ISO-8859 -1. 如果您选择 ISO-8859-1 很好,但是您必须在标题中使用它,而不是我的 UTF-8 示例,PHPMyAdmin 应该使用 ISO-8859-1 连接正确显示,否则您重新弄乱你的编码!
【解决方案3】:

使用 CDATA 包装数据。而不是 writeRaw() 使用 writeCData() 请参考下面的示例。

// CData output
$xml->startElement('title');
$xml->writeCData($row['station_subtitle']);
$xml->endElement();

【讨论】:

  • Firefox 抛出错误,我的应用程序 Firefox 也抛出错误:输出:XML 解析错误:格式不正确 位置:myserver.com/teststations.php 第 79 行,第 123 列:Nous vous souhaitons la plus cordiale bienvenue sur le site de la Radio Shalom Fm。 Nous sommes une station vanglique et nous sommes ouverts 24/24。 Nous vous offrons une programmation diversifie ax sur t ----------------------------------------- -------------------------------------------------- -------------------------------------------^
  • 您可以使用 CDATA 发布生成的 XML 吗?
  • 这对我有用:
  • 将所有内容都包装在 CDATA 中,除了确保我所有的表单都是 utf-8 之外,这似乎可以完成这项工作,所以也感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 2018-08-05
  • 2013-03-21
  • 2011-05-19
  • 1970-01-01
相关资源
最近更新 更多