1

I found a really weird behavior using SimpleXMLElement:

    $xmlstr = '<?xml version="1.0" standalone="yes"?>
<movies>
<movie>
    <title></title>
</movie>
</movies>';


$movies = new SimpleXMLElement($xmlstr);

$subelement = $movies->movie->title;

echo "Accesing normal: " . PHP_EOL;
echo var_dump($movies->movie->title) . PHP_EOL;
echo var_dump(empty($movies->movie->title)) . PHP_EOL;

echo "Accesing subelement: " . PHP_EOL;
echo var_dump($subelement) . PHP_EOL;
echo var_dump(empty($subelement)) . PHP_EOL;

The empty function is returning true when accessing the sub-elements using the main object, and is returning false when accessing the sub-elements using the variable containing the sub-element.

Why the behavior of empty is different if I pass the element in a variable than when I pass the element acceding from the main element?

Maybe empty is not the way to check for emptiness in this case, what is the correct way to check if the element is empty in a simpleXMLElement?

hakre
  • 193,403
  • 52
  • 435
  • 836
FerCa
  • 2,067
  • 3
  • 15
  • 18

2 Answers2

1

For me, it seems to be the same problem as mentioned in that bug report: https://bugs.php.net/bug.php?id=62717

Only solution I know is to check if your title is an empty string, or cast your variable to a string:

if($subelement == "")

OR

$subelement = (string)$movies->movie->title;

But if you use empty() after casting to string (maybe) another problem is, it would also be true if your movies title is e.g. 0 or some other (numeric) strings that seem to be empty, see: http://php.net/manual/en/function.empty.php - Return Values

This will work as expected:

<?php
$xmlstr = '<?xml version="1.0" standalone="yes"?>
<movies>
    <movie>
        <title>asdf</title>
    </movie>
</movies>';


$movies = new SimpleXMLElement($xmlstr);

$subelement = $movies->movie->title;

echo "Accesing normal: " . PHP_EOL;
 var_dump($movies->movie->title) . PHP_EOL;
 var_dump(empty($movies->movie->title)) . PHP_EOL; 
echo"<br><br>";
echo "Accesing subelement: " . PHP_EOL;
 var_dump($subelement) . PHP_EOL;
 var_dump($subelement == "") . PHP_EOL; string

Or with a cast to string:

<?php

$xmlstr = '<?xml version="1.0" standalone="yes"?>
<movies>
    <movie>
        <title>0</title>
    </movie>
</movies>';


$movies = new SimpleXMLElement($xmlstr);

$subelement = (string)$movies->movie->title;

echo "Accesing normal: " . PHP_EOL;
echo var_dump($movies->movie->title) . PHP_EOL;
echo var_dump(empty($movies->movie->title)) . PHP_EOL;
echo "<br>";
echo "Accesing subelement: " . PHP_EOL;
echo var_dump($subelement) . PHP_EOL;
echo var_dump(empty($subelement)) . PHP_EOL; 
bpoiss
  • 13,673
  • 3
  • 35
  • 49
0

Cast your object to a string first $subelement = (string)$movies->movie->title;, see also Getting actual value from PHP SimpleXML node

Community
  • 1
  • 1
Bass Jobsen
  • 48,736
  • 16
  • 143
  • 224