Skip to content

Commit a16c02f

Browse files
committed
Implement class for dynamic class constants
1 parent 6f93608 commit a16c02f

File tree

4 files changed

+38
-27
lines changed

4 files changed

+38
-27
lines changed

Zend/tests/dynamic_class_const_fetch.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ Warning: Undefined variable $barr in %s : eval()'d code on line %d
5252
Undefined constant Foo::
5353
string(3) "bar"
5454
string(3) "bar"
55-
Cannot dynamically fetch class constant "class"
56-
Cannot dynamically fetch class constant "class"
55+
string(3) "Foo"
56+
string(3) "Foo"
5757
Undefined constant Foo::42
5858
Undefined constant Foo::42
5959
Undefined constant Foo::42

Zend/tests/dynamic_class_const_fetch_cache_slot.phpt

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@ Dynamic class constant fetch
33
--FILE--
44
<?php
55

6-
class Foo {
6+
class FooParent {
77
public const BAR = 'bar';
88
public const BAZ = 'baz';
99
}
1010

11-
class Bar {
11+
class Foo extends FooParent {
12+
public const BAZ = 'baz child';
13+
}
14+
15+
class BarParent {
1216
public const BAR = 'bar 2';
1317
public const BAZ = 'baz 2';
1418
}
1519

20+
class Bar extends BarParent {
21+
public const BAZ = 'baz 2 child';
22+
}
23+
1624
function test($const) {
1725
echo Foo::{$const}, "\n";
1826
$foo = 'Foo';
@@ -25,18 +33,29 @@ test('BAZ');
2533
$c = function ($const) {
2634
echo self::{$const}, "\n";
2735
echo static::{$const}, "\n";
36+
echo parent::{$const}, "\n";
2837
};
2938

3039
$c->bindTo(null, Foo::class)('BAR');
3140
$c->bindTo(null, Bar::class)('BAZ');
41+
$c->bindTo(null, Foo::class)('class');
42+
$c->bindTo(null, Bar::class)('class');
3243

3344
?>
3445
--EXPECT--
3546
bar
3647
bar
37-
baz
38-
baz
48+
baz child
49+
baz child
3950
bar
4051
bar
52+
bar
53+
baz 2 child
54+
baz 2 child
4155
baz 2
42-
baz 2
56+
Foo
57+
Foo
58+
FooParent
59+
Bar
60+
Bar
61+
BarParent

Zend/zend_vm_def.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5907,12 +5907,10 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, AN
59075907
constant_name = zval_get_string(GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R));
59085908

59095909
if (zend_string_equals_literal_ci(constant_name, "class")) {
5910-
// FIXME: This should probably just be implemented, since it will work for folded constant expressions
5911-
zend_throw_error(NULL, "Cannot dynamically fetch class constant \"class\"");
5912-
ZVAL_UNDEF(EX_VAR(opline->result.var));
5910+
ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
59135911
zend_string_release_ex(constant_name, /* persistent */ false);
59145912
FREE_OP2();
5915-
HANDLE_EXCEPTION();
5913+
ZEND_VM_NEXT_OPCODE();
59165914
}
59175915
}
59185916
zv = zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name);
@@ -5958,6 +5956,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, AN
59585956
if (OP1_TYPE == IS_CONST && OP2_TYPE == IS_CONST) {
59595957
CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value);
59605958
}
5959+
zend_string_release_ex(constant_name, /* persistent */ false);
59615960
} else {
59625961
zend_throw_error(NULL, "Undefined constant %s::%s",
59635962
ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
@@ -5970,7 +5969,6 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, AN
59705969

59715970
ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value);
59725971

5973-
zend_string_release_ex(constant_name, /* persistent */ false);
59745972
FREE_OP2();
59755973
ZEND_VM_NEXT_OPCODE();
59765974
}

Zend/zend_vm_execute.h

Lines changed: 9 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)