Bug #51284 [Opn->Bgs]: foreach distroys objects in array
Edit report at http://bugs.php.net/bug.php?id=51284&edit=1
ID: 51284
Updated by: mike@php.net
Reported by: gerhard at tinned-software dot net
Summary: foreach distroys objects in array
-Status: Open
+Status: Bogus
Type: Bug
Package: Class/Object related
Operating System: MacOSX, Linux, ...
PHP Version: Irrelevant
New Comment:
I get a Warning: Parameter 2 to test_obj2::__construct() expected to be
a reference, value given in /tmp/phpbugs/51284.php on line 128
You lose the ref with func_get_args().
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
Thread (7 messages)