WordPress插件处理XML产品Feed时字符编码异常,库存值识别失败
解决XML Feed编码问题,正确识别"På lager"库存状态
问题根源
乱码"PÃ¥ lager"是典型的编码不匹配导致的:你的XML Feed声明使用iso-8859-1(Latin-1)编码,但PHP默认以UTF-8环境处理字符串,把Latin-1编码的字节直接当作UTF-8解析,就会出现这种乱码。
修改后的函数代码
function fetch_and_parse_product_feed_with_xmlreader($feed_entry) { $reader = new XMLReader(); if (!$reader->open($feed_entry['url'])) { echo "<p>Failed to open feed: " . esc_url($feed_entry['url']) . "</p>"; return array(); } $in_stock_products = array(); while ($reader->read()) { if ($reader->nodeType == XMLReader::ELEMENT) { if ($reader->localName == 'produkt') { // 读取XML并转换编码:从ISO-8859-1转为UTF-8 $productXml = mb_convert_encoding($reader->readOuterXML(), 'UTF-8', 'ISO-8859-1'); $product = simplexml_load_string($productXml); // 用mb_strtolower处理多字节字符,确保å转小写正确 $stock_status = mb_strtolower((string)$product->lagerantal); // 添加转码后的匹配条件 if ($stock_status === 'instock' || $stock_status === 'in stock' || intval($stock_status) > 0 || $stock_status === 'yes' || $stock_status === 'på lager') { $processed_url = process_url_for_comparison((string)$product->vareurl); $in_stock_products[] = $processed_url; } } elseif ($reader->localName == 'product') { $productXml = $reader->readOuterXML(); // 若type2的Feed也有编码问题,取消注释下方转码逻辑 // $productXml = mb_convert_encoding($productXml, 'UTF-8', 'ISO-8859-1'); $product = simplexml_load_string($productXml); $stock_status = mb_strtolower((string)$product->Instock); if ($stock_status === 'instock' || $stock_status === 'in stock' || intval($stock_status) > 0 || $stock_status === 'yes' || $stock_status === 'på lager') { // 统一添加该判断 $processed_url = process_url_for_comparison((string)$product->TrackingUrl); $in_stock_products[] = $processed_url; } } } } $reader->close(); return $in_stock_products; }
关键改动说明
- 编码转换:用
mb_convert_encoding将读取到的XML字符串从ISO-8859-1转为UTF-8,确保PHP后续字符串处理的编码一致性 - 多字节小写转换:替换
strtolower为mb_strtolower,避免多字节字符(如丹麦语的å)转小写时出错 - 统一判断条件:在两类Feed的库存判断中都加入
'på lager'的匹配,兼容不同Feed的库存标识
额外优化建议
如果你的Feed可能存在多种编码(不止ISO-8859-1),可以先从XML声明中提取编码,再动态转码:
// 提取XML编码 $encoding = 'UTF-8'; // 默认值 if (preg_match('/encoding="([^"]+)"/', $reader->readOuterXML(), $matches)) { $encoding = $matches[1]; } // 动态转码 $productXml = mb_convert_encoding($reader->readOuterXML(), 'UTF-8', $encoding);
内容的提问来源于stack exchange,提问作者Kasper Toft Braun
相关产品推荐
相关产品推荐

