is_array says array is not an array!

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
nickweavers
Forum Newbie
Posts: 4
Joined: Thu Feb 19, 2004 11:38 am
Contact:

is_array says array is not an array!

Post by nickweavers »

It is late, and I may be missing something very obvious here, but I am having trouble accessing the telephone values in some xml because when there is more than one number, simpleXml creates $xmlObj->TelephoneNumbers->TelephoneNumber as an array, but when there is only one, it creates it as SimpleXMLElement Object. If I try to use is_array() on $xmlObj->TelephoneNumbers->TelephoneNumber to determine whether I loop over it or not, the value I get back is false even though print_r() tells me it is an array, and if I actually use foreach on it, it behaves like an array. Can anyone tell me why is_array returns false?

My small testcase is below, followed by the results:

Code: Select all

<?php
function xmlentities($string) {
    return str_replace ( array ( '&', ' ', '"', "'", '<', '>' ), array ( '&', '&nbsp;' , '"', '&apos;' , '<' , '>' ), $string );
}

function is_array_abled(&$x)
{
    return (bool)($x instanceof ArrayAccess or is_array($x));
}

$xml = <<<EOD
<Applicants>
    <TelephoneNumbers>
        <TelephoneNumber>
            <Number>01244123456</Number>
            <Type>Notification</Type>
        </TelephoneNumber>
        <TelephoneNumber>
            <Number>78787654321</Number>
            <Type>Mobile</Type>
        </TelephoneNumber>
    </TelephoneNumbers>
</Applicants>
EOD;

printf("<h3>XML:</h3>");
print(nl2br(xmlentities($xml)));
$xmlObj = simplexml_load_string($xml);
printf("<h3>SimpleXML Object:</h3>");
print("<pre>");
print_r($xmlObj);
print("</pre>");

if(is_array($xmlObj->TelephoneNumbers->TelephoneNumber)) {
	$result = 'true';
} else {
	$result = 'false';
}

printf("is_array(\$xmlObj->TelephoneNumbers->TelephoneNumber) gives: %s<br><br>", $result);

// Try printing both sets of numbers
print("But using a foreach loop still works and we can print out the numbers...<br>");
foreach ($xmlObj->TelephoneNumbers->TelephoneNumber as $phoneObj) {
	printf("Phone: %s, Number: %s<br>", $phoneObj->Type, $phoneObj->Number);
}
?>
Produces:

Code: Select all

XML:
<Applicants>
    <TelephoneNumbers>
        <TelephoneNumber>
            <Number>01244123456</Number>
            <Type>Notification</Type>
        </TelephoneNumber>
        <TelephoneNumber>
            <Number>78787654321</Number>
            <Type>Mobile</Type>
        </TelephoneNumber>
    </TelephoneNumbers>
</Applicants>
SimpleXML Object:

SimpleXMLElement Object
(
    [TelephoneNumbers] => SimpleXMLElement Object
        (
            [TelephoneNumber] => Array
                (
                    [0] => SimpleXMLElement Object
                        (
                            [Number] => 01244123456
                            [Type] => Notification
                        )

                    [1] => SimpleXMLElement Object
                        (
                            [Number] => 78787654321
                            [Type] => Mobile
                        )

                )

        )

)

is_array($xmlObj->TelephoneNumbers->TelephoneNumber) gives: false

But using a foreach loop still works and we can print out the numbers...
Phone: Notification, Number: 01244123456
Phone: Mobile, Number: 78787654321
TIA.
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: is_array says array is not an array!

Post by Jonah Bron »

Try print_r()ing the value of just $xmlObj->TelephoneNumbers->TelephoneNumber ?
nickweavers
Forum Newbie
Posts: 4
Joined: Thu Feb 19, 2004 11:38 am
Contact:

Re: is_array says array is not an array!

Post by nickweavers »

I think the problem is with is_array(). The count() function seems to tell me something I can use; when $xmlObj->TelephoneNumbers->TelephoneNumber is a simpleXML Object it returns 1, and if it is an array (because the xml had more than one Telephone tag entry) it returns a number greater than one matching the number of Telephone tag entries.
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: is_array says array is not an array!

Post by John Cartwright »

$xmlObj->TelephoneNumbers->TelephoneNumber would actually represent a SimpleXMLElement, which contains an array of child elements. It is being reported as an array, and still works as an array is because it implements Traversable.

To get your desired results, you would need to either check if its an instance of Traversable, or cast it to an array.

Code: Select all

if ($xmlObj->TelephoneNumbers->TelephoneNumber instanceof Traversable) {}

//or 

// Would actually always return true, since we are casting it directly to an array
// Therefore, would be more appropriate to cast and use count()
if (is_array((array)$xmlObj->TelephoneNumbers->TelephoneNumber)) {}
aramix
Forum Newbie
Posts: 1
Joined: Thu Mar 13, 2014 6:52 am

Re: is_array says array is not an array!

Post by aramix »

The problem is that it is an object not array. So you should use is_object() instead.
Post Reply