Aha! That was the inspiration I needed to get the right combination of "&"s. The following bit of code behaves differently under 4.3 vs 4.4:
<?php function f(&$a) { return $a; } $x = array('a','b','c'); foreach (array_keys($x) as $k) { // I think the following line disconnects $y in 4.3 // but leaves $y connected in 4.4 $y =& f($x[$k]); $z[] =& $y; } var_dump($x); var_dump($z); ?> My guess would be that in 4.3 the engine tries to do the reference even though it may be dangerous. That would "disconnect" $y from the previous $z[]. 4.4 knows the reference is impossible and leaves $y connected to the previous $z[]. Is that analysis correct, engine gurus? Thanks, Colin! - Todd On Fri, 2005-09-16 at 10:55 +1000, Colin Tucker wrote: > Hello again, > > Wow, this thread generated more heat than I thought it would, I > basically just wanted to know the reasoning behind making the change to > PHP4, unfortunate I guess for all involved that it went downhill. I > have learned much in the past few days, at any rate. > > As mentioned, my code actually broke following the switch to 4.4.0, in > addition to logging hundreds of E_NOTICE errors. It's taken me some > time to track down where it's going wrong, but I think I've found out > the culprits involved. It's complicated, I'll try to explain it all. > > The problem was related to components of my web app framework (which is > similar to Struts, and incidently, now being phased out for a MUCH more > lightweight, PHP5-based framework), in particular, an array of > attributes, view helper classes and the creation of DAOs (data access > objects) at runtime via XML configuration, which would look like this: > > <daos> > <dao name="dao.freight" > class="FreightDAO" > component="Generic/Commerce/DAO/FreightDAO.php" /> > <dao name="dao.customer" > class="CustomerDAO" > component="Generic/Commerce/DAO/CustomerDAO.php" /> > <dao name="dao.order.status" > class="OrderStatusDAO" > component="Generic/Commerce/DAO/OrderStatusDAO.php" /> > </daos> > > This XML would be parsed and the relevant DAO instances would be created > and recorded in attribute scope for the current application module > instance. For each dao node, the following code would be called (where > $daoClass and $daoComponent are extracted from the XML attributes): > > $dao =& $this->_createDAO($daoClass,$daoComponent); > > if ($dao) > { > $this->module->setAttributeByReference($name,$dao); > } > > Notice it assigns by reference, however I discovered that the > _createDAO() method was not *returning* by reference: > > function _createDAO($daoClass=null,$daoComponent=null) > { > > // Obtain Database Object: > > $database =& $this->module->findDatabase(); > > if (is_null($database)) > { > trigger_error($this->error(ERROR_DB_COULD_NOT_OBTAIN)); > } > else > { > > // Obtain Database Connection: > > $connection =& $database->getConnection(); > > if (is_null($connection)) > { > trigger_error($this->error(ERROR_DB_COULD_NOT_CONNECT)); > } > else > { > > // Create DAO Instance: > > $cmp =& new ClassComponent($daoClass,$daoComponent); > > $dao =& $cmp->getInstance(); > > if ($dao) > { > $dao->setConnectionByReference($connection); > > return $dao; > } > } > } > > return NULL; > > } > > What was happening under PHP 4.4.0 is when the newly created DAO was > added to the module as an attribute (setAttributeByReference), a new > attribute would be created, but ALL existing DAOs in the attribute scope > would become the newly added DAO, for example: > > (create and set the dao.freight attribute): > > attributes (array) > { > [dao.freight] => FreightDAO Object > } > > (create and set the dao.customer attribute): > > attributes (array) > { > [dao.freight] => CustomerDAO Object > [dao.customer] => CustomerDAO Object > } > > (create and set the dao.order.status attribute): > > attributes (array) > { > [dao.freight] => OrderStatusDAO Object > [dao.customer] => OrderStatusDAO Object > [dao.order.status] => OrderStatusDAO Object > } > > Simply by adding the ampersand to the _createDAO() method, like so: > > function &_createDAO($daoClass=null,$daoComponent=null) > { > } > > ...rectified the problem (however did not make hundreds of E_NOTICE's > disappear, of course ;)). > > The question is, why did this problem not occur before 4.4.0? Is this > an example of the "memory corruption"? > > Regards, > > Colin. > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php