File tree Expand file tree Collapse file tree 5 files changed +108
-0
lines changed
tests/classes/inner_classes Expand file tree Collapse file tree 5 files changed +108
-0
lines changed Original file line number Diff line number Diff line change @@ -2080,9 +2080,15 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
20802080 if (constructor ) {
20812081 if (UNEXPECTED (!(constructor -> op_array .fn_flags & ZEND_ACC_PUBLIC ))) {
20822082 zend_class_entry * scope = get_fake_or_executed_scope ();
2083+ check_lexical_scope :
20832084 if (UNEXPECTED (constructor -> common .scope != scope )) {
20842085 if (UNEXPECTED (constructor -> op_array .fn_flags & ZEND_ACC_PRIVATE )
20852086 || UNEXPECTED (!zend_check_protected (zend_get_function_root_class (constructor ), scope ))) {
2087+ if (scope && scope -> lexical_scope ) {
2088+ scope = scope -> lexical_scope ;
2089+ goto check_lexical_scope ;
2090+ }
2091+
20862092 zend_bad_constructor_call (constructor , scope );
20872093 zend_object_store_ctor_failed (zobj );
20882094 constructor = NULL ;
Original file line number Diff line number Diff line change 1+ --TEST--
2+ usage in an enum
3+ --FILE--
4+ <?php
5+
6+ enum Outer {
7+ class Inner {}
8+ }
9+
10+ var_dump (new Outer :>Inner ());
11+ var_dump (class_exists (Outer:>Inner::class));
12+ ?>
13+ --EXPECT--
14+ object(Outer:>Inner)#1 (0) {
15+ }
16+ bool(true)
Original file line number Diff line number Diff line change 1+ --TEST--
2+ usage in an interface
3+ --FILE--
4+ <?php
5+
6+ interface Outer {
7+ class Inner {}
8+ }
9+
10+ var_dump (new Outer :>Inner ());
11+
12+ class Foo implements Outer {}
13+
14+ var_dump (class_exists (Outer:>Inner::class));
15+ var_dump (class_exists (Foo:>Inner::class));
16+ ?>
17+ --EXPECT--
18+ object(Outer:>Inner)#1 (0) {
19+ }
20+ bool(true)
21+ bool(false)
Original file line number Diff line number Diff line change 1+ --TEST--
2+ usage inside a trait
3+ --FILE--
4+ <?php
5+
6+ trait Outer {
7+ class Inner {}
8+ }
9+
10+ var_dump (new Outer :>Inner ());
11+
12+ class Foo {
13+ use Outer;
14+ }
15+
16+ var_dump (class_exists (Outer:>Inner::class));
17+ var_dump (class_exists (Foo:>Inner::class));
18+
19+ ?>
20+ --EXPECT--
21+ object(Outer:>Inner)#1 (0) {
22+ }
23+ bool(true)
24+ bool(false)
Original file line number Diff line number Diff line change 1+ --TEST--
2+ constructors
3+ --FILE--
4+ <?php
5+
6+ class User {
7+ public private(set) string $ name ;
8+ public private(set) string $ email ;
9+
10+ private function __construct (self :>Builder $ builder ) {
11+ $ this ->name = $ builder ->name ;
12+ $ this ->email = $ builder ->email ;
13+ }
14+
15+ public readonly final class Builder {
16+ public function __construct (public private(set ) string |null $ name = null , public private(set ) string |null $ email = null ) {}
17+
18+ public function withEmail (string $ email ): self {
19+ return new self ($ this ->name , $ email );
20+ }
21+
22+ public function withName (string $ name ): self {
23+ return new self ($ name , $ this ->email );
24+ }
25+
26+ public function build (): User {
27+ return new User ($ this );
28+ }
29+ }
30+ }
31+
32+ $ user = new User :>Builder ()->withName ('Rob ' )->withEmail ('rob@example.com ' )->build ();
33+ var_dump ($ user );
34+ ?>
35+ --EXPECT--
36+ object(User)#2 (2) {
37+ ["name"]=>
38+ string(3) "Rob"
39+ ["email"]=>
40+ string(15) "rob@example.com"
41+ }
You can’t perform that action at this time.
0 commit comments