Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a75901c

Browse files
add tests for more scenarios
1 parent cc1be75 commit a75901c

File tree

2 files changed

+168
-12
lines changed

2 files changed

+168
-12
lines changed

‎ext/reflection/tests/ReflectionClass_newInstanceFromData_001.phpt‎

Lines changed: 135 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class A
1717
class B
1818
{
1919
public int $a;
20-
public string $b;
20+
public readonlystring $b;
2121
}
2222

2323
class C
@@ -29,42 +29,140 @@ class D
2929
{
3030
}
3131

32+
class E
33+
{
34+
public function __construct(
35+
public int $a,
36+
public string $b,
37+
)
38+
{}
39+
}
40+
41+
class F
42+
{
43+
public readonly int $a;
44+
45+
public function __construct(
46+
public readonly string $b,
47+
)
48+
{}
49+
}
50+
51+
class G
52+
{
53+
public readonly int $a;
54+
public readonly string $b;
55+
56+
public function __construct()
57+
{
58+
$this->b = 456;
59+
}
60+
}
61+
62+
class H
63+
{
64+
public int $a {
65+
set(int $value) => $value + 1;
66+
}
67+
}
68+
69+
class I
70+
{
71+
public int $a;
72+
73+
public int $b {
74+
get => $this->a + 1;
75+
set(int $value) {
76+
$this->a = $value - 1;
77+
}
78+
}
79+
}
80+
3281

3382
$rcA = new ReflectionClass('A');
3483
$rcB = new ReflectionClass('B');
3584
$rcC = new ReflectionClass('C');
3685
$rcD = new ReflectionClass('D');
86+
$rcE = new ReflectionClass('E');
87+
$rcF = new ReflectionClass('F');
88+
$rcG = new ReflectionClass('G');
89+
$rcH = new ReflectionClass('H');
90+
$rcI = new ReflectionClass('I');
3791

92+
// assign bad data type to normal class
3893
try
3994
{
4095
$rcA->newInstanceFromData(['a' => 'bad', 'b' => 123], ['foo', 1337]);
96+
echo "you should not see this\n";
4197
}
4298
catch(Throwable $e)
4399
{
44100
echo "Exception: " . $e->getMessage() . "\n";
45101
}
46102

103+
// normal class with constructor
47104
var_dump($rcA->newInstanceFromData(['a' => 123, 'b' => 'good'], ['foo', 1337]));
48105

106+
// normal class with no constructor and a readonly property
49107
var_dump($rcB->newInstanceFromData(['a' => 123, 'b' => 'good']));
50108

51-
var_dump($rcC->newInstanceFromData(['a' => 123, 'b' => 'good']));
52-
53-
var_dump($rcC->newInstanceFromData([]));
109+
// trying to set dynamic properties on class without AllowDynamicProperties attribute
110+
var_dump($rcC->newInstanceFromData(['a' => 123, 'b' => 'good'])); // this should warn
111+
var_dump($rcC->newInstanceFromData([]));// this is fine
54112

113+
// setting dynamic properties on a class with AllowDynamicProperties attribute
55114
var_dump($rcD->newInstanceFromData(['a' => 123, 'b' => 'good']));
56115

116+
// class with property promotion
117+
try
118+
{
119+
$rcE->newInstanceFromData(['a' => 123, 'b' => 'good']); // no constructor args will fail
120+
echo "you should not see this\n";
121+
}
122+
catch(Throwable $e)
123+
{
124+
echo "Exception: " . $e->getMessage() . "\n";
125+
}
126+
127+
var_dump($rcE->newInstanceFromData(['a' => 123, 'b' => 'good'], [456, 'foo'])); // constructor args will override class props
128+
129+
// class with readonly promoted property
130+
var_dump($rcF->newInstanceFromData(['a' => 123], ['b' => 'good']));
131+
132+
// readonly property set in the constructor
133+
try
134+
{
135+
$rcG->newInstanceFromData(['a' => 123, 'b' => 'good']); // setting $b by data will conflict with constructor's set
136+
echo "you should not see this\n";
137+
}
138+
catch(Throwable $e)
139+
{
140+
echo "Exception: " . $e->getMessage() . "\n";
141+
}
142+
143+
// hooked set property
144+
var_dump($rcH->newInstanceFromData(['a' => 1]));
145+
146+
// virtual property
147+
var_dump($rcI->newInstanceFromData(['a' => 1, 'b' => 2]));
148+
149+
$instance = $rcI->newInstanceFromData(['a' => 1]);
150+
var_dump($instance);
151+
var_dump($instance->b);
152+
$instance->b = 3;
153+
var_dump($instance->b);
154+
57155
?>
58156
--EXPECTF--
59157
Exception: Cannot assign string to property A::$a of type int
60158
In constructor of class A
61-
object(A)#5 (2) {
159+
object(A)#%d (2) {
62160
["a"]=>
63161
int(123)
64162
["b"]=>
65163
string(4) "good"
66164
}
67-
object(B)#5 (2) {
165+
object(B)#%d (2) {
68166
["a"]=>
69167
int(123)
70168
["b"]=>
@@ -74,17 +172,45 @@ object(B)#5 (2) {
74172
Deprecated: Creation of dynamic property C::$a is deprecated in %s on line %d
75173

76174
Deprecated: Creation of dynamic property C::$b is deprecated in %s on line %d
77-
object(C)#5 (2) {
175+
object(C)#%d (2) {
78176
["a"]=>
79177
int(123)
80178
["b"]=>
81179
string(4) "good"
82180
}
83-
object(C)#5 (0) {
181+
object(C)#%d (0) {
84182
}
85-
object(D)#5 (2) {
183+
object(D)#%d (2) {
86184
["a"]=>
87185
int(123)
88186
["b"]=>
89187
string(4) "good"
90188
}
189+
Exception: Too few arguments to function E::__construct(), 0 passed and exactly 2 expected
190+
object(E)#%d (2) {
191+
["a"]=>
192+
int(456)
193+
["b"]=>
194+
string(3) "foo"
195+
}
196+
object(F)#%d (2) {
197+
["a"]=>
198+
int(123)
199+
["b"]=>
200+
string(4) "good"
201+
}
202+
Exception: Cannot modify readonly property G::$b
203+
object(H)#%d (1) {
204+
["a"]=>
205+
int(2)
206+
}
207+
object(I)#%d (1) {
208+
["a"]=>
209+
int(1)
210+
}
211+
object(I)#%d (1) {
212+
["a"]=>
213+
int(1)
214+
}
215+
int(2)
216+
int(3)

‎ext/reflection/tests/ReflectionClass_newInstanceFromData_002.phpt‎

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
--TEST--
2-
ReflectionClass::newInstanceFromData - internal class
2+
ReflectionClass::newInstanceFromData - bad instantiations
33
--FILE--
44
<?php
55

6-
$rcDateTime = new ReflectionClass('DateTime');
7-
$rcPDOStatement = new ReflectionClass('PDOStatement');
6+
// internal classes
7+
$rcDateTime = new ReflectionClass('DateTime'); // with constructor
8+
$rcPDOStatement = new ReflectionClass('PDOStatement'); // no constructor
9+
10+
// not classes
11+
$rcStringable = new ReflectionClass('Stringable');
12+
13+
interface MyInterface {}
14+
$rcMyInterface = new ReflectionClass('MyInterface');
15+
16+
trait MyTrait {}
17+
$rcMyTrait = new ReflectionClass('MyTrait');
818

919
try
1020
{
@@ -24,7 +34,27 @@ catch(Throwable $e)
2434
echo "Exception: " . $e->getMessage() . "\n";
2535
}
2636

37+
try
38+
{
39+
$rcMyInterface->newInstanceFromData(['a' => 123]);
40+
}
41+
catch(Throwable $e)
42+
{
43+
echo "Exception: " . $e->getMessage() . "\n";
44+
}
45+
46+
try
47+
{
48+
$rcMyTrait->newInstanceFromData(['a' => 123]);
49+
}
50+
catch(Throwable $e)
51+
{
52+
echo "Exception: " . $e->getMessage() . "\n";
53+
}
54+
2755
?>
2856
--EXPECTF--
2957
Exception: Class DateTime is an internal class that cannot be instantiated from data
3058
Exception: Class PDOStatement is an internal class that cannot be instantiated from data
59+
Exception: Cannot instantiate interface MyInterface
60+
Exception: Cannot instantiate trait MyTrait

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /