PHP XML编码错误-使用XMLWriter
我试图找到解决办法,但我找不到。我正在研究Laravel,并试图创建动态XML文档。我正在使用PHP XML编码错误-使用XMLWriter,php,xml,laravel,encoding,xmlwriter,Php,Xml,Laravel,Encoding,Xmlwriter,我试图找到解决办法,但我找不到。我正在研究Laravel,并试图创建动态XML文档。我正在使用XMLWriter。我在控制器中的方法: public function feed_xml() { header('Content-type: text/xml; charset=UTF-8'); $sql = "SELECT ic.id, i.description, c.name, ca.name as category_name, i.tags, i
XMLWriter
。我在控制器中的方法:
public function feed_xml() {
header('Content-type: text/xml; charset=UTF-8');
$sql = "SELECT ic.id, i.description, c.name, ca.name as category_name, i.tags,
i.image_folder, i.image, i.price
FROM msrd.item i, msrd.collection c, msrd.category ca, msrd.item_collection ic
WHERE i.active = 't' AND i.collection_id = c.id AND ca.id = i.category_id AND ic.item_id = i.id AND ic.original = true";
$data = \DB::connection('test-connection')->select($sql);
$seo_array = \Config::get('engine.seo_keywords');
$xml = new \XMLWriter;
$xml->openUri('php://output');
$xml->setIndent(true); //debug only
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('feed');
$xml->startAttribute('xmlns');
$xml->text('http://www.w3.org/2005/Atom');
$xml->endAttribute();
$xml->startAttribute('xmlns:g');
$xml->text('http://base.google.com/ns/1.0');
$xml->endAttribute();
$xml->startElement('title');
$xml->text('MySite');
$xml->endElement();
$xml->startElement('link');
$xml->writeAttribute('rel', 'self');
$xml->writeAttribute('href', "http://exampl/feed.xml");
$xml->endElement();
foreach ($data as $row) {
$xml->startElement('entry');
$xml->startElement('g:id');
$xml->text($row->id);
$xml->endElement();
$xml->startElement('g:title');
$xml->writeCData(preg_replace('/[^a-zA-Z0-9\s]/', '', $this->utf8_tohtml($this->utf8_bad_replace(trim(substr($row->category_name, 0, 100))))));
$xml->endElement();
$xml->writeElement('g:availability', 'in stock');
$xml->startElement('g:description');
$xml->writeCData(ucfirst(strtolower(preg_replace('/[^a-zA-Z0-9\s]/', '', $this->utf8_tohtml($this->utf8_bad_replace(trim(substr($row->description, 0, 500))))))));
$xml->endElement();
$xml->startElement('g:link');
$seo_text = $seo_array[($row->id % sizeof($seo_array))];
$xml->writeCData('http://example.com/subpage/' . $row->id . '/' . str_replace(" ", "-", trim(strtolower($seo_text . ' ' . $row->category_name . ' ' . $row->tags))));
$xml->endElement();
$xml->writeElement('g:image_link', 'http://example.com/common/fb_img_output.php?item_collection_id=' . $row->id . '&visual_id=3&image_width=1200&image_height=628&container_width=1200&container_height=628&image_folder=' . $row->image_folder . '&image=' . $row->image);
$xml->writeElement('g:condition', 'new');
$xml->writeElement('g:brand', 'MySite');
$xml->writeElement('g:price', $row->price . ' USD');
$xml->writeElement('g:google_product_category', 'Product Category');
$xml->endElement();
}
$xml->endElement();
$xml->endDocument();
}
我的帮助功能:
private function utf8_tohtml($str) {
$ret = '';
$max = strlen($str);
$last = 0; // keeps the index of the last regular character
for ($i = 0; $i < $max; $i++) {
$c = $str{$i};
$c1 = ord($c);
if ($c1 >> 5 == 6) { // 110x xxxx, 110 prefix for 2 bytes unicode
$ret .= substr($str, $last, $i - $last); // append all the regular characters we've passed
$c1 &= 31; // remove the 3 bit two bytes prefix
$c2 = ord($str{ ++$i}); // the next byte
$c2 &= 63; // remove the 2 bit trailing byte prefix
$c2 |= (($c1 & 3) << 6); // last 2 bits of c1 become first 2 of c2
$c1 >>= 2; // c1 shifts 2 to the right
$ret .= '&#' . ($c1 * 100 + $c2) . ';'; // this is the fastest string concatenation
$last = $i + 1;
}
}
return $ret . substr($str, $last, $i); // append the last batch of regular characters
}
private function utf8_bad_replace($str, $replace = '') {
$UTF8_BAD = '([\x00-\x7F]' . # ASCII (including control chars)
'|[\xC2-\xDF][\x80-\xBF]' . # non-overlong 2-byte
'|\xE0[\xA0-\xBF][\x80-\xBF]' . # excluding overlongs
'|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}' . # straight 3-byte
'|\xED[\x80-\x9F][\x80-\xBF]' . # excluding surrogates
'|\xF0[\x90-\xBF][\x80-\xBF]{2}' . # planes 1-3
'|[\xF1-\xF3][\x80-\xBF]{3}' . # planes 4-15
'|\xF4[\x80-\x8F][\x80-\xBF]{2}' . # plane 16
'|(.{1}))'; # invalid byte
ob_start();
while (preg_match('/' . $UTF8_BAD . '/S', $str, $matches)) {
if (!isset($matches[2])) {
echo $matches[0];
} else {
echo $replace;
}
$str = substr($str, strlen($matches[0]));
}
$result = ob_get_contents();
ob_end_clean();
return $result;
}
私有函数utf8\u tohtml($str){
$ret='';
$max=strlen($str);
$last=0;//保留最后一个正则字符的索引
对于($i=0;$i<$max;$i++){
$c=$str{$i};
$c1=作战需求文件($c);
如果($c1>>5==6){//110x xxxx,2字节unicode的110前缀
$ret.=substr($str,$last,$i-$last);//附加我们传递的所有常规字符
$c1&=31;//删除3位两字节前缀
$c2=ord($str{++$i});//下一个字节
$c2&=63;//删除2位尾随字节前缀
$c2 |=($c1&3)>=2;//c1向右移动2
$ret.=''($c1*100+$c2)。“;”;//这是最快的字符串连接
$last=$i+1;
}
}
返回$ret.substr($str,$last,$i);//追加最后一批常规字符
}
私有函数utf8\u bad\u replace($str,$replace=''){
$UTF8_BAD='([\x00-\x7F]'。#ASCII(包括控制字符)
“|[\xC2-\xDF][\x80-\xBF]”。非超长2字节
“|\xE0[\xA0-\xBF][\x80-\xBF]”不包括超长的
“|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}”。#直接3字节
“|\xED[\x80-\x9F][\x80-\xBF]。#不包括代理项
“|\xF0[\x90-\xBF][\x80-\xBF]{2}.”平面1-3
“|[\xF1-\xF3][\x80-\xBF]{3}.”平面4-15
“|\xF4[\x80-\x8F][\x80-\xBF]{2}.”平面16
“|(.{1}))”#无效字节
ob_start();
while(preg_match('/'.$UTF8_BAD.'/S',$str,$matches)){
如果(!isset($matches[2])){
echo$匹配项[0];
}否则{
回声$替换;
}
$str=substr($str,strlen($matches[0]);
}
$result=ob_get_contents();
ob_end_clean();
返回$result;
}
我什么都做不了。我正在尝试使用return\Response::make($xml,'200')->header('Content-Type','text/xml');
但它工作不正常。我不知道我需要做什么,我的生成器不工作,并显示下一个错误:
删除标题,以便查看结果。然后,在这里给我们输入。@MrD我找到了解决方案-我需要将
header()
中的字符集更改为ISO-8859-1
。如果ISO-8859-1是解决方案,请不要将UTF-8写入文档:$xml->startDocument('1.0',UTF-8'))
-另外,请仅发布一个包含足够代码的最小示例,以重现您的问题。不仅仅是您首先遇到问题,然后想询问的所有代码。我的建议是始终从头开始创建一个新示例,尽可能少的代码和数据重现问题(隔离问题)它不是我的数据库,它是我工作的基础,所以我不能给你它们的内容:<我只能说它是XML解析器在下一个字母上给出了错误:ç
,è
,等等。