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

Reply via email to