Ошибка кодировки PHP XML — использование 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.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;
}

Я ничего не могу сделать. Я пытаюсь использовать return \Response::make($xml, '200')->header('Content-Type', 'text/xml'); но это не работает нормально. Я не знаю, что мне нужно сделать, мой генератор не работает и показывает следующую ошибку:

ошибка

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]