From:             
Operating system: MacOSX, Linux, ...
PHP version:      Irrelevant
Package:          Class/Object related
Bug Type:         Bug
Bug description:foreach distroys objects in array

Description:
------------
I have a script which tries to create configured objects of classes. The 

method creating the object of the named class will generate a unique 

identifier to be able to identify the invocation later in the class. This 

unique_id is basically calculated by adding the class name and all 

constructor parameters into a ":"-seperetaed list. For doing this i used 



This all functions well as long as there is not the following very special


combination of parameters and class-parameterlist. If one of the parameters


is an object, and this object is passed to the class as reference
(&$object).



In such a case, the foreach loop destroys somehow the $parameter array. As


the $parameter array is not altered in the loop, there is no explanation to


my way the loop influence the array. 



To prove that the loop is causing this problem i changed the loop from 

foreach() to for(). As you can see in the test script there are 2 methods
in 

the OM class. The get_object_OK() uses the for()-loop to generate the ID
and

the get_object_NOK() method uses the foreach()-loop to generate it.



With the for()-loop the script runs without any troubles. But with the 

foreach()-loop the script returns an error while invocating the object.
This 

error causes the object to be not created.



The error message which can be found in the webserver's / php's logfile is


the following:

[error] [client 127.0.0.1] PHP Warning:  Invocation of test_obj2's
constructor failed in /.../test.php on line 183, referer:
http://127.0.0.1:8080/

... The line references to "$obj =
$reflection_obj->newInstanceArgs($parameter);" at the get_object_NOK.()
function.



Test script:
---------------
class test_obj

{

    var $test = "abc";

    

    function __construct($str)

    {

        $this->test = $str;

    }

    

    function get()

    { 

        echo get_class($this)." - string=".$this->test."<br />\n";

    }

    

    function set($str)

    {

        $test = $str;

    }

}



class test_obj2

{

    var $test = "abc";

    

    function __construct($string1, &$object)

    {

        echo get_class($this)." - string1=$string1<br />\n";

        $object->get();

    }

}











//include_once(dirname(__FILE__).'/object_manager.class.php');

//include_once(dirname(__FILE__).'/element_container.class.php');





//

// Test execution

//

echo "PHP Version: ".phpversion()."<br /><br />\n";

$om = new OM();



$t1 = new test_obj("init-text-object-1");

$t1->get();

echo "Object of class 'Test_CLass' ... Finished.<br />\n";





$t2 = $om->get_object_OK("test_obj2", "object-text-2", $t1);

echo "Object of class 'Test_CLass2' with for() loop ... Finished.<br
/>\n";



$t2 = $om->get_object_NOK("test_obj2", "object-text-2", $t1);

echo "Object of class 'Test_CLass2' with foreach() loop ... Finished.<br
/>\n";









//

// A short testing code from a much biger function / Class to 

// demonstrate the behaviour

//

class OM

{

    function get_object_OK()

    {

        $parameter = func_get_args();

        $type = array_shift($parameter);

        

        //

        // create unique identifier for this object creation.

        // Used in the original class to identify the object later in the
class.

        //

        $unique_id = "$type:";

        // loop through all parameters

        for($i=0; $i < count($parameter); $i++)

        {

            // if parameter is an object, get only the object name

            if(is_object($parameter[$i]) === TRUE)

            {

                $unique_id .= get_class($parameter[$i]).':';

                continue;

            }

            // get the variable content as string to the identifier-string

            $unique_id .= gettype($parameter[$i]).':';

        }

        

        //

        // Creating the object by name

        //

        $reflection_obj = new ReflectionClass($type);      

        $obj = $reflection_obj->newInstanceArgs($parameter); 

        

        // return the created object

        return $obj;

    }

    

    function get_object_NOK()

    {

        $parameter = func_get_args();

        $type = array_shift($parameter);

        

        //

        // create unique identifier for this object creation.

        // Used in the original class to identify the object later in the
class.

        //

        $unique_id = "$type:";

        // loop through all parameters

        foreach($parameter as $key => $param)

        {

            // if parameter is an object, get only the object name

            if(is_object($param) === TRUE)

            {

                $unique_id .= get_class($param).':';

                continue;

            }

            // get the variable content as string to the identifier-string

            $unique_id .= gettype($param).':';

        }

        

        //

        // Creating the object by name

        //

        $reflection_obj = new ReflectionClass($type);      

        $obj = $reflection_obj->newInstanceArgs($parameter); 

        

        // return the created object

        return $obj;

    }

}



Expected result:
----------------
The script should successfully create an object when for() or
foreach()-loop 

is used.



Actual result:
--------------
The script works only with for()-loop. When the foreach look is used, the 

following error message is shown.

[error] [client 127.0.0.1] PHP Warning:  Invocation of test_obj2's
constructor failed in /.../test.php on line 183, referer:
http://127.0.0.1:8080/

... The line references to "$obj =
$reflection_obj->newInstanceArgs($parameter);" at the get_object_NOK.()
function.



-- 
Edit bug report at http://bugs.php.net/bug.php?id=51284&edit=1
-- 
Try a snapshot (PHP 5.2):            
http://bugs.php.net/fix.php?id=51284&r=trysnapshot52
Try a snapshot (PHP 5.3):            
http://bugs.php.net/fix.php?id=51284&r=trysnapshot53
Try a snapshot (PHP 6.0):            
http://bugs.php.net/fix.php?id=51284&r=trysnapshot60
Fixed in SVN:                        
http://bugs.php.net/fix.php?id=51284&r=fixed
Fixed in SVN and need be documented: 
http://bugs.php.net/fix.php?id=51284&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=51284&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=51284&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=51284&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=51284&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=51284&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=51284&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=51284&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=51284&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=51284&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=51284&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=51284&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=51284&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=51284&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=51284&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=51284&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=51284&r=mysqlcfg

Reply via email to