Skip to content

Commit 30b23c7

Browse files
committed
Make interface constants overridable by default
1 parent e40fe6d commit 30b23c7

File tree

9 files changed

+79
-55
lines changed

9 files changed

+79
-55
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Interface constants can be overridden directly
3+
--FILE--
4+
<?php
5+
6+
interface I
7+
{
8+
const X = 1;
9+
}
10+
11+
class C implements I
12+
{
13+
const X = 2;
14+
}
15+
16+
?>
17+
--EXPECT--
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Final interface constants cannot be overridden directly
3+
--FILE--
4+
<?php
5+
6+
interface I
7+
{
8+
final public const X = 1;
9+
}
10+
11+
class C implements I
12+
{
13+
const X = 2;
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: C::X cannot override final constant I::X in %s on line %d
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Final interface constants can be inherited
3+
--FILE--
4+
<?php
5+
6+
interface I
7+
{
8+
final public const X = 1;
9+
}
10+
11+
class C implements I
12+
{
13+
}
14+
15+
?>
16+
--EXPECT--
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Interface constants can be overridden indirectly
3+
--FILE--
4+
<?php
5+
6+
interface I
7+
{
8+
const X = 1;
9+
}
10+
11+
class C implements I {}
12+
13+
class D extends C
14+
{
15+
const X = 2;
16+
}
17+
18+
?>
19+
--EXPECT--

Zend/tests/inter_01.phpt

Lines changed: 0 additions & 18 deletions
This file was deleted.

Zend/zend_API.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4316,7 +4316,7 @@ ZEND_API zend_class_constant *zend_declare_class_constant_ex(zend_class_entry *c
43164316
zend_class_constant *c;
43174317

43184318
if (ce->ce_flags & ZEND_ACC_INTERFACE) {
4319-
if (access_type != ZEND_ACC_PUBLIC) {
4319+
if (!(access_type & ZEND_ACC_PUBLIC)) {
43204320
zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface constant %s::%s must be public", ZSTR_VAL(ce->name), ZSTR_VAL(name));
43214321
}
43224322
}

Zend/zend_inheritance.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,14 @@ static bool do_inherit_constant_check(HashTable *child_constants_table, zend_cla
14791479

14801480
if (zv != NULL) {
14811481
old_constant = (zend_class_constant*)Z_PTR_P(zv);
1482-
if (old_constant->ce != parent_constant->ce) {
1482+
1483+
if ((ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_FINAL)) {
1484+
zend_error_noreturn(E_COMPILE_ERROR, "%s::%s cannot override final constant %s::%s",
1485+
ZSTR_VAL(old_constant->ce->name), ZSTR_VAL(name), ZSTR_VAL(iface->name), ZSTR_VAL(name)
1486+
);
1487+
}
1488+
1489+
if (old_constant->ce != parent_constant->ce && old_constant->ce->ce_flags & ZEND_ACC_INTERFACE) {
14831490
zend_error_noreturn(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", ZSTR_VAL(name), ZSTR_VAL(iface->name));
14841491
}
14851492
return 0;

tests/classes/interface_constant_inheritance_002.phpt

Lines changed: 0 additions & 16 deletions
This file was deleted.

tests/classes/interface_constant_inheritance_003.phpt

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)