Skip to content

Clone with #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion Zend/tests/assert/expect_015.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ assert(0 && ($a = function () {
$x = $a ?? $b;
[$a, $b, $c] = [1, 2 => 'x', 'z' => 'c'];
@foo();
$y = clone $x;
$y = \clone($x);
yield 1 => 2;
yield from $x;
}))
Expand Down
49 changes: 49 additions & 0 deletions Zend/tests/clone/ast.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--TEST--
Ast Printing
--FILE--
<?php

$x = new stdClass();


try {
assert(false && $y = clone $x);
} catch (Error $e) {
echo $e->getMessage(), PHP_EOL;
}

try {
assert(false && $y = clone($x));
} catch (Error $e) {
echo $e->getMessage(), PHP_EOL;
}

try {
assert(false && $y = clone($x, foo: $foo, bar: $bar));
} catch (Error $e) {
echo $e->getMessage(), PHP_EOL;
}

try {
assert(false && $y = clone($x, ...$array));
} catch (Error $e) {
echo $e->getMessage(), PHP_EOL;
}

try {
assert(false && $y = clone($x, ...[
"foo" => $foo,
"bar" => $bar,
]));
} catch (Error $e) {
echo $e->getMessage(), PHP_EOL;
}


?>
--EXPECT--
assert(false && ($y = \clone($x)))
assert(false && ($y = \clone($x)))
assert(false && ($y = \clone($x, foo: $foo, bar: $bar)))
assert(false && ($y = \clone($x, ...$array)))
assert(false && ($y = \clone($x, ...['foo' => $foo, 'bar' => $bar])))
5 changes: 3 additions & 2 deletions Zend/tests/clone/bug36071.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ $a = clone 0;
$a[0]->b = 0;
?>
--EXPECTF--
Fatal error: Uncaught Error: __clone method called on non-object in %sbug36071.php:2
Fatal error: Uncaught TypeError: clone(): Argument #1 ($object) must be of type object, int given in %s:%d
Stack trace:
#0 {main}
#0 %s(%d): clone(0)
#1 {main}
thrown in %sbug36071.php on line 2
5 changes: 3 additions & 2 deletions Zend/tests/clone/bug42817.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ $a = clone(null);
array_push($a->b, $c);
?>
--EXPECTF--
Fatal error: Uncaught Error: __clone method called on non-object in %sbug42817.php:2
Fatal error: Uncaught TypeError: clone(): Argument #1 ($object) must be of type object, null given in %s:%d
Stack trace:
#0 {main}
#0 %s(%d): clone(NULL)
#1 {main}
thrown in %sbug42817.php on line 2
5 changes: 3 additions & 2 deletions Zend/tests/clone/bug42818.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Bug #42818 ($foo = clone(array()); leaks memory)
$foo = clone(array());
?>
--EXPECTF--
Fatal error: Uncaught Error: __clone method called on non-object in %sbug42818.php:2
Fatal error: Uncaught TypeError: clone(): Argument #1 ($object) must be of type object, array given in %s:%d
Stack trace:
#0 {main}
#0 %s(%d): clone(Array)
#1 {main}
thrown in %sbug42818.php on line 2
24 changes: 24 additions & 0 deletions Zend/tests/clone/callback.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
As Callback
--FILE--
<?php

class Foo {
private function __clone() {

}

public function clone_me() {
return array_map(clone(...), [$this]);
}
}

$f = new Foo();

$clone = $f->clone_me()[0];

var_dump($f !== $clone);

?>
--EXPECT--
bool(true)
5 changes: 3 additions & 2 deletions Zend/tests/clone/clone_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ $a = clone array();

?>
--EXPECTF--
Fatal error: Uncaught Error: __clone method called on non-object in %s:%d
Fatal error: Uncaught TypeError: clone(): Argument #1 ($object) must be of type object, array given in %s:%d
Stack trace:
#0 {main}
#0 %s(%d): clone(Array)
#1 {main}
thrown in %s on line %d
5 changes: 3 additions & 2 deletions Zend/tests/clone/clone_003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ $a = clone $b;
--EXPECTF--
Warning: Undefined variable $b in %s on line %d

Fatal error: Uncaught Error: __clone method called on non-object in %s:%d
Fatal error: Uncaught TypeError: clone(): Argument #1 ($object) must be of type object, null given in %s:%d
Stack trace:
#0 {main}
#0 %s(%d): clone(NULL)
#1 {main}
thrown in %s on line %d
81 changes: 81 additions & 0 deletions Zend/tests/clone/clone_with_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
--TEST--
Clone with basic
--FILE--
<?php

class Dummy { }

$x = new stdClass();

$foo = 'FOO';
$bar = new Dummy();
$array = [
'baz' => 'BAZ',
'array' => [1, 2, 3],
];

function gen() {
yield 'from_gen' => 'value';
}

var_dump(clone $x);
var_dump(clone($x));
var_dump(clone($x, foo: $foo, bar: $bar));
var_dump(clone($x, ...$array));
var_dump(clone($x, ...['obj' => $x]));

var_dump(clone($x, ...[
'abc',
'def',
new Dummy(),
'named' => 'value',
]));

var_dump(clone($x, ...gen()));

?>
--EXPECTF--
object(stdClass)#%d (0) {
}
object(stdClass)#%d (0) {
}
object(stdClass)#%d (2) {
["foo"]=>
string(3) "FOO"
["bar"]=>
object(Dummy)#%d (0) {
}
}
object(stdClass)#%d (2) {
["baz"]=>
string(3) "BAZ"
["array"]=>
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
}
object(stdClass)#%d (1) {
["obj"]=>
object(stdClass)#%d (0) {
}
}
object(stdClass)#%d (4) {
["0"]=>
string(3) "abc"
["1"]=>
string(3) "def"
["2"]=>
object(Dummy)#%d (0) {
}
["named"]=>
string(5) "value"
}
object(stdClass)#%d (1) {
["from_gen"]=>
string(5) "value"
}
114 changes: 114 additions & 0 deletions Zend/tests/clone/clone_with_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
--TEST--
Clone with respects visiblity
--FILE--
<?php

class P {
public $a = 'default';
protected $b = 'default';
private $c = 'default';
public private(set) string $d = 'default';

public function m1() {
return clone($this, a: 'updated A', b: 'updated B', c: 'updated C', d: 'updated D');
}
}

class C extends P {
public function m2() {
return clone($this, a: 'updated A', b: 'updated B', c: 'dynamic C');
}

public function m3() {
return clone($this, d: 'inaccessible');
}
}

class Unrelated {
public function m3(P $p) {
return clone($p, b: 'inaccessible');
}
}

$p = new P();

var_dump(clone($p, a: 'updated A'));
var_dump($p->m1());

$c = new C();
var_dump($c->m1());
var_dump($c->m2());
try {
var_dump($c->m3());
} catch (Error $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}

try {
var_dump(clone($p, b: 'inaccessible'));
} catch (Error $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}

try {
var_dump(clone($p, d: 'inaccessible'));
} catch (Error $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}

try {
var_dump((new Unrelated())->m3($p));
} catch (Error $e) {
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
}

?>
--EXPECTF--
object(P)#%d (4) {
["a"]=>
string(9) "updated A"
["b":protected]=>
string(7) "default"
["c":"P":private]=>
string(7) "default"
["d"]=>
string(7) "default"
}
object(P)#%d (4) {
["a"]=>
string(9) "updated A"
["b":protected]=>
string(9) "updated B"
["c":"P":private]=>
string(9) "updated C"
["d"]=>
string(9) "updated D"
}
object(C)#%d (4) {
["a"]=>
string(9) "updated A"
["b":protected]=>
string(9) "updated B"
["c":"P":private]=>
string(9) "updated C"
["d"]=>
string(9) "updated D"
}

Deprecated: Creation of dynamic property C::$c is deprecated in %s on line %d
object(C)#%d (5) {
["a"]=>
string(9) "updated A"
["b":protected]=>
string(9) "updated B"
["c":"P":private]=>
string(7) "default"
["d"]=>
string(7) "default"
["c"]=>
string(9) "dynamic C"
}
Error: Cannot modify private(set) property P::$d from scope C
Error: Cannot access protected property P::$b
Error: Cannot modify private(set) property P::$d from global scope
Error: Cannot access protected property P::$b
23 changes: 23 additions & 0 deletions Zend/tests/clone/clone_with_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
Clone with supports property hooks
--FILE--
<?php

class Clazz {
public string $hooked = 'default' {
set (string $value) {
$this->hooked = strtoupper($value);
}
}
}

$c = new Clazz();

var_dump(clone($c, hooked: 'updated'));

?>
--EXPECTF--
object(Clazz)#%d (1) {
["hooked"]=>
string(7) "UPDATED"
}
Loading
Loading