|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2014-07-04 13:10 UTC] ondrej@php.net
Description: ------------ As reported here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=729476 Original report is for 5.4.x (Debian wheezy). --begin-- The documented behaviour of the empty() function is to be a shorthand for "!isset($var) || var == false". The below example shows a case where this fails, and was triggering a subtle bug in my code after upgrade of production server to Wheezy. I think this may well affect others and even be a security issue if "empty" variables are assumed to be safe. I noticed the issue running PHP under Apache but for simplicity the below example can just be run on the command line. I've not tested on any later PHP version, sorry. --end-- I have retested this on 5.6.0RC2. And what's even more strange, that if I add var_dump($value) to the last loop, I will get: ---cut here-- object(SimpleXMLElement)#5 (0) { } ---cut here-- even though dereferencing $value returns 'somevalue' correctly. Test script: --------------- <?php $foo = 'bar'; print "regular string ... "; var_dump(empty($foo)); #Should be false $xml = simplexml_load_string("<xml><something>somevalue</something></xml>"); $xml2 = simplexml_load_string("<xml>\n<something>somevalue</something>\n</xml>"); foreach($xml as $key => $value) { print "$key = $value ... "; var_dump(empty($value)); # Should be false var_dump($value == false); # Should be false } foreach($xml2 as $key => $value) { print "$key = $value ... "; var_dump(empty($value)); # Should be false, but isn't var_dump($value == false); # Should be false } ?> Expected result: ---------------- regular string ... bool(false) something = somevalue ... bool(false) bool(false) something = somevalue ... bool(false) bool(false) Actual result: -------------- regular string ... bool(false) something = somevalue ... bool(false) bool(false) something = somevalue ... bool(true) bool(false) PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 20:00:01 2025 UTC |
I have a work-around, of sorts. I hope someone is investigating this bug because it is pretty awful. I do not know how to solve the foreach() loop presented in ondrej's post, but if you're accessing elements individually, it seems that leaving off the "[0]" subscript works. Don't ask me why! See the test case below. If you run this test with the assignment from "A" rather than "A[0]", it works. <?php function testfunc($str){ echo "Testing on \"$str\"\n"; $xml = new SimpleXMLElement($str); $a = $xml->A[0]; //$a = $xml->A; echo "$a"; if ($a) { $result = 1; } else { $result = 0; } echo " $result \n\n"; return $result; } $r1 = testfunc ("<head><A>hello</A></head>"); $r2 = testfunc ("<head><A>first</A><A>hello</A> </head>"); if ($r1 && !$r2) echo " Test fails: white space makes 'A' element disappear! \n";