Edit report at http://bugs.php.net/bug.php?id=51284&edit=1

 ID:               51284
 Comment by:       crillemannen at live dot se
 Reported by:      gerhard at tinned-software dot net
 Summary:          foreach distroys objects in array
 Status:           Open
 Type:             Bug
 Package:          Class/Object related
 Operating System: MacOSX, Linux, ...
 PHP Version:      Irrelevant

 New Comment:

the best site ever http://www.crismas.se


Previous Comments:
------------------------------------------------------------------------
[2010-03-12 13:29:44] gerhard at tinned-software dot net

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 this bug report at http://bugs.php.net/bug.php?id=51284&edit=1

Reply via email to