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