PHP中未终止的实体引用

69

这是我的代码:

<?php
// 27/01/2016 Edit:
$result = mysql_query("A Long mysql query");
$rss = new SimpleXMLElement('<rss version="2.0" />');
$products = $rss->addChild('products');
///
while($row = mysql_fetch_array($result)){
$product = $products->addChild('category');
$product->addChild('product_id',"$row[product_id]");
$product->addChild('cat_id',"$row[cat_id]");
$product->addChild('cat_name',"$row[cat_name]");
$product->addchild('product_code',"$row[product_code]");
$product->addchild('product_name',"$row[product_name]");
$product->addChild('description','$row[description]');
$product->addchild('rating',"$row[rating]");
$product->addchild('image_url','$row[imag_url]');
$product->addchild('price',"$row[price]");
$product->addchild('discount',"$row[discount]");
$product->addchild('stock_status',"$row[stock_status]");
$product->addchild('stock_quantity',"$row[stock_quantity]");
$product->addchild('weight',"$row[weight]");
$product->addchild('length',"$row[length]");
$product->addchild('width',"$row[width]");
$product->addchild('height',"$row[height]");
$product->addchild('colour',"$row[colour]");
$product->addchild('size',"$row[size]");
$product->addchild('material',"$row[material]");
$product->addchild('pattern',"$row[pattern]");
};

Header('Content-type: text/xml');
print($rss->asXML());
?>

而这里是错误信息:

警告:SimpleXMLElement :: addChild()[simplexmlelement.addchild]:在C:\ wamp \ www \ rabwah \ core.php第40行中未终止的实体引用_Coke.jpg

错误出现在包含'$row [imag_url]'的那一行。


4
Obligatory: mysql_*函数将在PHP 5.5中被弃用。不建议编写新代码,因为它将来会被移除。相反,应使用MySQLiPDO来成为更好的PHP开发人员。 - Jason McCreary
'$row[imag_url]' 应该改为 "$row[imag_url]"。需要将单引号修改为双引号。同时你在 $rss->addChild('<products'); 中忘了加上 /> - gen_Eric
不知道这是否相关,但 addChild 是方法而不是 addchild,另外这一行 $products = $rss->addChild('<products'); 似乎有误。 - Orangepill
3
@RocketHazmat、@jason McCreary和@Orangepill,$rss->addChild('<products');的问题已经修复,现在应该改为$rss->addChild('products');,但问题仍然存在。 - mega6382
7个回答

160

这样可以正确地编码 & < > 以及 "" ''

$parent->addChild($name, htmlspecialchars($value));

47

SimpleXMLElement 实际上是一种表现像对象的系统资源,这使得在循环中使用它有些棘手。因此,在尝试添加新的子元素时,不要使用以下方法:

$product->addchild('element', $value);

做这个:

$product->element = $value;

或者你可以使用htmlspecialchars()函数来转义HTML特殊字符。

注意:

mysql_*版本中已经被弃用,在版本中已经移除。因此,请改用mysqli_*PDO

为什么不应该在PHP中使用mysql_*函数?


9

我的解决方案是专门创建一个文本节点,以确保所有内容都得到了适当的转义:

$cell = $dom->createElement('td');
$cell->appendChild($dom->createTextNode($value));

3
这不是SimpleXMLElement,而是DOMDocument。 - ermannob
2
@ermannob DOMDocument确实有createTextNode方法:http://php.net/manual/en/domdocument.createtextnode.php - Kavi Siegel

3
如果您使用新创建的节点,可以通过访问{0}属性来设置值。这应该转义任何特殊字符。
$childNode = $parent->addChild($name);
$childNode{0} = $value;

1
抱歉重新提出一个旧问题,但这里有另一种解决方法.. 假设以下代码导致了“未终止的实体引用”错误:
$xml->addChild($key,$value); 

"Joel-Davey的解决方案非常有效:"
$xml->addChild($key,htmlspecialchars($value)); 

但是如果由于某些原因你不想使用上述的htmlspecialchars函数,你也可以采用以下方法进行操作(基本上,你可以将一步操作分成两步):

$xml->addChild($key); 
$xml->$key=$value; 

我不知道哪个会更快地执行;我怀疑这不会有太大的差异,但是这个方法可行,我认为应该提一下。
PS:我知道它可行,因为我正在一个个人项目中使用它。

当然可以!在我的(非常基本的)测试中,第二个使用了比第一个多一点超小的内存,但似乎执行速度略快一点。 - Peter
@mega6382:我添加了一个链接到我的个人项目,你可以在“野外”中看到它的运行情况。 - Peter

0

尝试通过更改 -

$product->addchild('image_url','$row[imag_url]');

$product->addchild('image_url',"$row[\"imag_url\"]");

或者

$product->addchild('image_url',$row['imag_url']);

编辑 在image_url周围也加上引号,感谢Barrmar的贡献。


0

正确的形式是:

$product->addchild('image_url',htmlspecialchars($row['imag_url']));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接