Code: Select all
$c = array(new stdClass(), new stdClass());
$d = clone $c;Code: Select all
Warning: __clone method called on non-objectModerator: General Moderators
Code: Select all
$c = array(new stdClass(), new stdClass());
$d = clone $c;Code: Select all
Warning: __clone method called on non-objectcmon volka! its not some php n00b you are talking to here.volka wrote:see http://de2.php.net/language.types.array
If they can make it so it triggers an error when you use clone on a array then they could have it return the array with cloned objects. I personally feel its a hole in the functionality of the language.d11wtq wrote:PHP is not OO on the underbelly such as it's primitive types like array. There is ArrayObject in SPL but it doesn't work like an ordinary array.
The manual is not only for n00bs.ole wrote:cmon volka! its not some php n00b you are talking to here.volka wrote:see http://de2.php.net/language.types.array
It's a simple non-object trigger and has nothing more to do with passing an array to clone than passing a number or a resource, you'll get the same message. Does that mean there must also be extra code for cloining numbers and resources?d11wtq wrote:If they can make it so it triggers an error when you use clone on a array then they could have it return the array with cloned objects. I personally feel its a hole in the functionality of the language.
The bit on the array type is.The manual is not only for n00bs.
Yes you are probably right but does that mean that cloning objects in arrays directly clone isn't doable? I seriously doubt it.It's a simple non-object trigger and has nothing more to do with passing an array to clone than passing a number or a resource, you'll get the same message. Does that mean there must also be extra code for cloining numbers and resources?
Code: Select all
<?php
class MyClass {
public function __clone() {
echo 'cloning';
}
}
function fnclone($a) {
if (is_object($a))
return clone $a;
else
return null;
}
$arr = array(new MyClass, new MyClass);
$a2 = array_map('fnclone', $arr);
?>Code: Select all
/**
* Recursively iterates over an array cloning any objects encountered
*
* @param array $toClone
* @return array
*/
static public function arrayRecursiveClone(array $toClone)
{
foreach ($toClone as $k => $v) {
if (is_object($v)) {
$toClone[$k] = clone $v;
continue;
}
if (is_array($v)) {
$toClone[$k] = self::arrayRecursiveClone($v);
}
}
return $toClone;
}Code: Select all
public function testArrayRecursiveClone()
{
$zim = new stdClass();
$zim->gir = 10;
$foo = array(true, 10, array('string', array($zim)), 'string');
$bar = OF::arrayRecursiveClone($foo);
$zim->gir = 20;
$this->assertNotIdentical($bar[2][1][0], $zim);
$this->assertEqual($bar[2][1][0]->gir, 10);
}Code: Select all
static public function arrayRecursiveClone(array $toClone)Code: Select all
if ( is_object($o) ) {
$o2 = clone $o;
}
else {
$o2 = arrayRecursiveClone($o);
}Code: Select all
<?php
class MyClass {
private $prop;
public function __construct() { $this->prop = rand(1,99); }
public function __clone() { echo 'cloning '. $this->prop . "\n"; }
}
function clonex($toClone)
{
if (is_object($toClone)) {
return clone $toClone;
}
else if (is_array($toClone)) {
return array_map('clonex', $toClone);
}
else if (is_null($toClone)) {
return null;
}
else {
trigger_error('clonex: cloning not implemented for type:'.gettype($toClone), E_USER_WARNING);
return $toClone;
}
}
$arr = array(new MyClass, array(new MyClass, new MyClass), 3);
print_r($arr);
$arr2 = clonex($arr);
?>