Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ PHP NEWS
undefined). (Peter Kokot)
. Fixed bug GH-15565 (--disable-ipv6 during compilation produces error
EAI_SYSTEM not found). (nielsdos)
. Implemented asymmetric visibility for properties. (ilutov)

- Date:
. Fixed bug GH-13773 (DatePeriod not taking into account microseconds for end
Expand Down
43 changes: 43 additions & 0 deletions Zend/tests/asymmetric_visibility/__set.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
--TEST--
Asymmetric visibility __set
--FILE--
<?php

class Foo {
public private(set) string $bar;

public function setBar($bar) {
$this->bar = $bar;
}

public function unsetBar() {
unset($this->bar);
}

public function __set(string $name, mixed $value) {
echo __CLASS__, '::', __METHOD__, "\n";
}
}

$foo = new Foo();
try {
$foo->bar = 'baz';
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

$foo->setBar('baz');
try {
$foo->bar = 'baz';
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

$foo->unsetBar();
$foo->bar = 'baz';

?>
--EXPECT--
Cannot modify private(set) property Foo::$bar from global scope
Cannot modify private(set) property Foo::$bar from global scope
Foo::Foo::__set
47 changes: 47 additions & 0 deletions Zend/tests/asymmetric_visibility/__unset.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
--TEST--
Asymmetric visibility __unset
--FILE--
<?php

class Foo {
public private(set) string $bar;

public function setBar($bar) {
$this->bar = $bar;
}

public function unsetBar() {
unset($this->bar);
}

public function __unset($name) {
echo __METHOD__, "\n";
}
}

function test($foo) {
try {
unset($foo->bar);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
}

$foo = new Foo();
test($foo);

$foo->unsetBar();
test($foo);

$foo->setBar('bar');
test($foo);

$foo->unsetBar();
test($foo);

?>
--EXPECT--
Cannot unset private(set) property Foo::$bar from global scope
Foo::__unset
Cannot unset private(set) property Foo::$bar from global scope
Foo::__unset
28 changes: 28 additions & 0 deletions Zend/tests/asymmetric_visibility/ast_printing.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
private(set) protected(set) ast printing
--INI--
zend.assertions=1
assert.exception=1
--FILE--
<?php

try {
assert(function () {
class Foo {
public private(set) string $bar;
public protected(set) string $baz;
}
} && false);
} catch (Error $e) {
echo $e->getMessage();
}

?>
--EXPECT--
assert(function () {
class Foo {
public private(set) string $bar;
public protected(set) string $baz;
}

} && false)
33 changes: 33 additions & 0 deletions Zend/tests/asymmetric_visibility/bug001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--TEST--
Unset from __unset respects set visibility
--FILE--
<?php

class C {
public private(set) int $a = 1;
public function __construct() {
unset($this->a);
}
}

class D extends C {
public function __unset($name) {
unset($this->a);
}
}

$c = new D();
try {
unset($c->a);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
var_dump($c);

?>
--EXPECTF--
Cannot unset private(set) property C::$a from scope D
object(D)#%d (0) {
["a"]=>
uninitialized(int)
}
33 changes: 33 additions & 0 deletions Zend/tests/asymmetric_visibility/bug002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--TEST--
Set from __set respects set visibility
--FILE--
<?php

class C {
public private(set) int $a = 1;
public function __construct() {
unset($this->a);
}
}

class D extends C {
public function __set($name, $value) {
$this->a = $value;
}
}

$c = new D();
try {
$c->a = 2;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
var_dump($c);

?>
--EXPECTF--
Cannot modify private(set) property C::$a from scope D
object(D)#%d (0) {
["a"]=>
uninitialized(int)
}
28 changes: 28 additions & 0 deletions Zend/tests/asymmetric_visibility/bug003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--TEST--
Explicitly unset property with a-vis still respects set visibility
--FILE--
<?php

class C {
public private(set) int $a = 1;
public function __construct() {
unset($this->a);
}
}

$c = new C();
try {
$c->a = 2;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
unset($c->a);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

?>
--EXPECT--
Cannot modify private(set) property C::$a from global scope
Cannot unset private(set) property C::$a from global scope
18 changes: 18 additions & 0 deletions Zend/tests/asymmetric_visibility/bug004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
Missing property initialization for private(set) constructor promoted property
--FILE--
<?php

class T {
public function __construct(
private(set) string $prop,
) {}
}
var_dump(new T('Test'));

?>
--EXPECTF--
object(T)#%d (1) {
["prop"]=>
string(4) "Test"
}
14 changes: 14 additions & 0 deletions Zend/tests/asymmetric_visibility/cpp_no_type.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
Asymmetric visibility in CPP with no type
--FILE--
<?php

class Foo {
public function __construct(
public private(set) $bar,
) {}
}

?>
--EXPECTF--
Fatal error: Property with asymmetric visibility Foo::$bar must have type in %s on line %d
32 changes: 32 additions & 0 deletions Zend/tests/asymmetric_visibility/cpp_private.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
Asymmetric visibility private(set) CPP
--FILE--
<?php

class Foo {
public function __construct(
public private(set) string $bar,
) {}

public function setBar($bar) {
$this->bar = $bar;
}
}

$foo = new Foo('bar');
var_dump($foo->bar);

try {
$foo->bar = 'baz';
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

$foo->setBar('baz');
var_dump($foo->bar);

?>
--EXPECT--
string(3) "bar"
Cannot modify private(set) property Foo::$bar from global scope
string(3) "baz"
42 changes: 42 additions & 0 deletions Zend/tests/asymmetric_visibility/cpp_protected.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--TEST--
Asymmetric visibility protected(set) CPP
--FILE--
<?php

class Foo {
public function __construct(
public protected(set) string $bar,
) {}

public function setBarPrivate($bar) {
$this->bar = $bar;
}
}

class FooChild extends Foo {
public function setBarProtected($bar) {
$this->bar = $bar;
}
}

$foo = new FooChild('bar');
var_dump($foo->bar);

try {
$foo->bar = 'baz';
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

$foo->setBarPrivate('baz');
var_dump($foo->bar);

$foo->setBarProtected('qux');
var_dump($foo->bar);

?>
--EXPECT--
string(3) "bar"
Cannot modify protected(set) property Foo::$bar from global scope
string(3) "baz"
string(3) "qux"
14 changes: 14 additions & 0 deletions Zend/tests/asymmetric_visibility/cpp_wider_set_scope.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
Asymmetric visibility private(get) protected(set) in CPP is not allowed
--FILE--
<?php

class Foo {
public function __construct(
private protected(set) string $bar
) {}
}

?>
--EXPECTF--
Fatal error: Visibility of property Foo::$bar must not be weaker than set visibility in %s on line %d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Asymmetric visibility private(get) private(set) is allowed
--FILE--
<?php

class Foo {
private private(set) string $bar;
}

?>
===DONE===
--EXPECT--
===DONE===
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
Asymmetric visibility private(get) protected(set) not allowed
--FILE--
<?php

class Foo {
private protected(set) string $bar;
}

?>
--EXPECTF--
Fatal error: Visibility of property Foo::$bar must not be weaker than set visibility in %s on line %d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Asymmetric visibility protected(get) protected(set) is allowed
--FILE--
<?php

class Foo {
protected protected(set) string $bar;
}

?>
===DONE===
--EXPECT--
===DONE===
Loading