From: davydm at gmail dot com
Operating system: Linux
PHP version: 4.4.0
PHP Bug Type: Class/Object related
Bug description: Named variable array not correctly returned from within
member function
Description:
------------
I have a class which maintains heirachical data, as would be (and, indeed,
is) represented with xml. The class basically provides a programmable
interface to an xml data transport, allowing for data to be transported
from php to a tcl middleware server to be parsed and used. So far, so
good.
The best way to explain is to demonstrate:
If I were to load an instance of the object with the following xml:
<data>
<name>Foo</name>
<descr>Bar</descr>
<child>
<name>Childname</name>
<descr>Childdescr></descr>
</child>
</data>
I would get an object which has:
$obj->name == "Foo"
$obj->descr == "Bar"
$obj->child[0]->name == "Childname"
$obj->child[0]->descr == "Childdescr"
and so forth. The class allows for nodes with the same name, which are
then placed into an an array, hence the array notation on the child node
above.
The oddity I have hit upon seems to be a PHP bug, but I'm well open to
suggestions. In programming the class, I wanted a consistent interface
with the TCL class I have that handles the same functionality, so there
are times when I have replicated interface functions even when they are
not necessairly required (for the sake of completeness). One such
interface mirroring is the get_child function, which takes in the
following arguments:
$childname (string)
$idx (integer)
and returns a reference to the child named by the $childname and pointed
to by the $idx (if there is one).
The wierdness is that in the original implementation of get_child, where I
just checked that the child name was known and the key existed in the
array, I did:
return $this->$childname[$idx];
once I had verified with array_key_exists that the element actually
existed, I *always* got back null. If I referenced the child from outside
of the class (with $obj->childname[$idx]), the child object is quite
alright and there, and alive and all of that.
The wierdness steps up a notch when I change the internals of get_child:
instead of just returning the object with:
return $this->$childname[$idx];
I do:
foreach ($this->$childname as $cidx => $child) {
if ($cidx == $idx) {
return $child;
}
}
and VOILA!, I get back the child I was looking for. The code is less
efficient, of course, because I have to iterate over the child array. But
that's not the thing that really bothers me -- I'm more bothered as to
*why* this happens, and the only explanation I can see is something
lower-level and internal to PHP
Reproduce code:
---------------
Please have a look at http://dascafe.lesbean.net/hdobj.php.gz , starting
at line 289, which is the function definition for get_child. You can also
see that I've used a foreach in the function toXML(), instead of using the
child indeces and the child_count function, as I originally intended. If I
can supply more code, please let me know.
Expected result:
----------------
With the commented out code in place, I expect a reference to a member
variable of the class which is itself an object of the same class.
Actual result:
--------------
When I use the commented out code, I get a NULL reference instead of the
object. Using the foreach to iterate over each element in the $childname
array, and returning the child with a matching index works -- although
they should have exactly the same result.
--
Edit bug report at http://bugs.php.net/?id=34069&edit=1
--
Try a CVS snapshot (php4): http://bugs.php.net/fix.php?id=34069&r=trysnapshot4
Try a CVS snapshot (php5.0):
http://bugs.php.net/fix.php?id=34069&r=trysnapshot50
Try a CVS snapshot (php5.1):
http://bugs.php.net/fix.php?id=34069&r=trysnapshot51
Fixed in CVS: http://bugs.php.net/fix.php?id=34069&r=fixedcvs
Fixed in release: http://bugs.php.net/fix.php?id=34069&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=34069&r=needtrace
Need Reproduce Script: http://bugs.php.net/fix.php?id=34069&r=needscript
Try newer version: http://bugs.php.net/fix.php?id=34069&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=34069&r=support
Expected behavior: http://bugs.php.net/fix.php?id=34069&r=notwrong
Not enough info:
http://bugs.php.net/fix.php?id=34069&r=notenoughinfo
Submitted twice:
http://bugs.php.net/fix.php?id=34069&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=34069&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=34069&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=34069&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=34069&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=34069&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=34069&r=float
No Zend Extensions: http://bugs.php.net/fix.php?id=34069&r=nozend
MySQL Configuration Error: http://bugs.php.net/fix.php?id=34069&r=mysqlcfg