Skip to content

Commit bd2a00a

Browse files
committed
Merge branch 'PHP-7.2' into PHP-7.3
2 parents 5c221bc + 5388143 commit bd2a00a

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 7.3.4
44

5+
- Core:
6+
. Fixed bug #77652 (Anonymous classes can lose their interface information).
7+
(Nikita)
8+
59
- MySQLi:
610
. Fixed bug #77597 (mysqli_fetch_field hangs scripts). (Nikita)
711

Zend/tests/bug77652.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
return [
3+
'I' => function() {
4+
return new class implements I {};
5+
},
6+
];

Zend/tests/bug77652.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Bug #77652: Anonymous classes can lose their interface information
3+
--FILE--
4+
<?php
5+
6+
interface I {}
7+
require __DIR__ . '/bug77652.inc';
8+
$data = require __DIR__ . '/bug77652.inc';
9+
print_r(class_implements($data['I']()));
10+
11+
?>
12+
--EXPECT--
13+
Array
14+
(
15+
[I] => I
16+
)

Zend/zend_compile.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6440,10 +6440,32 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
64406440
if (!zend_hash_exists(CG(class_table), lcname)) {
64416441
zend_hash_add_ptr(CG(class_table), lcname, ce);
64426442
} else {
6443-
/* this anonymous class has been included */
6443+
/* This anonymous class has been included, reuse the existing definition.
6444+
* NB: This behavior is buggy, and this should always result in a separate
6445+
* class declaration. However, until the problem of RTD key collisions is
6446+
* solved, this gives a behavior close to what is expected. */
64446447
zval zv;
64456448
ZVAL_PTR(&zv, ce);
64466449
destroy_zend_class(&zv);
6450+
ce = zend_hash_find_ptr(CG(class_table), lcname);
6451+
6452+
/* Manually replicate emission of necessary inheritance opcodes here. We cannot
6453+
* reuse the general code, as we only want to emit the opcodes, without modifying
6454+
* the reused class definition. */
6455+
if (ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS) {
6456+
zend_emit_op(NULL, ZEND_BIND_TRAITS, &declare_node, NULL);
6457+
}
6458+
if (implements_ast) {
6459+
zend_ast_list *iface_list = zend_ast_get_list(implements_ast);
6460+
uint32_t i;
6461+
for (i = 0; i < iface_list->children; i++) {
6462+
opline = zend_emit_op(NULL, ZEND_ADD_INTERFACE, &declare_node, NULL);
6463+
opline->op2_type = IS_CONST;
6464+
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
6465+
zend_resolve_class_name_ast(iface_list->child[i]));
6466+
}
6467+
zend_emit_op(NULL, ZEND_VERIFY_ABSTRACT_CLASS, &declare_node, NULL);
6468+
}
64476469
return;
64486470
}
64496471
} else {

0 commit comments

Comments
 (0)