SimpleXMLのバグ #66084 の影響
とあるAPIから返されたXMLをparseしたところ、環境により結果が違っていた。
どうも、Bug #66084 の修正が影響しているらしい。
この修正は php-5.6.11, php-5.5.27, php-5.4.28 で取り込まれている。
現象
レスポンスXML
foo
がスペース、その後なぜか改行がついている行儀の悪いXML。
<?xml version="1.0" encoding="UTF-8"?><root><foo> </foo> </root>
再現phpコード
$strXml =<<<'EOF' <?xml version="1.0" encoding="UTF-8"?><root><foo> </foo> </root> EOF; $objXml = new SimpleXMLElement($strXml); var_dump($objXml);
php-5.5.6 の結果
class SimpleXMLElement#1 (1) { public $foo => class SimpleXMLElement#2 (0) { } }
php-5.6.11 の結果
class SimpleXMLElement#1 (1) { public $foo => class SimpleXMLElement#2 (1) { public ${0} => string(1) " " } }
今回の例だと、foo
がホワイトスペースで構成されていて、
foo
の直後にホワイトスペースが存在する場合に
foo
が空だと判断されていまっていたようで、
新しいバージョンでは正常にスペースが取得できている。
正しい方向への修正なのだけど、今回みたいな行儀の悪いXMLをparseしている場合は動作に影響がある。
値自体は、(string)$objXml->foo
でピンポイントになら取得できる。
全体の構造のparseがおかしいので、foreach にかけたりしているとまずい。
こんなのとか
static public function xml2Array(\SimpleXMLElement $objXml) { $f = function($elem, $out=[]) use (&$f) { if(empty($elem)) { return null; } foreach((array)$elem as $key=>$node) { if(is_object($node) || is_array($node)) { $out[$key] = $f($node); } else { $out[$key] = $node; } } return $out; }; $arrXml = $f($objXml); return $arrXml; }