Skip to content

Commit 7d3f8a5

Browse files
committed
Allow same original method names if possible to disambiguate with alias
1 parent d4210d5 commit 7d3f8a5

File tree

4 files changed

+111
-5
lines changed

4 files changed

+111
-5
lines changed

Zend/tests/traits/bug74872a.phpt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
Bug #74872 (First Trait wins on importing same methods with diff alias)
3+
--FILE--
4+
<?php
5+
6+
trait Trait1
7+
{
8+
public function init()
9+
{
10+
echo("Trait1 - init\n");
11+
}
12+
}
13+
14+
trait Trait2
15+
{
16+
public function init()
17+
{
18+
echo("Trait2 - init\n");
19+
}
20+
}
21+
22+
class Test
23+
{
24+
use Trait1 {
25+
init as public method1trait1;
26+
}
27+
28+
use Trait2 {
29+
init as public method1trait2;
30+
}
31+
32+
final public function __construct()
33+
{
34+
$this->method1trait1();
35+
$this->method1trait2();
36+
}
37+
}
38+
39+
$test = new Test();
40+
41+
$reflection = new ReflectionClass( $test );
42+
43+
foreach($reflection->getTraitAliases() as $k => $v)
44+
{
45+
echo $k.' => '.$v."\n";
46+
}
47+
?>
48+
--EXPECT--
49+
Trait1 - init
50+
Trait2 - init
51+
method1trait1 => Trait1::init
52+
method1trait2 => Trait2::init

Zend/tests/traits/bug74872b.phpt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
Bug #74872 (First Trait wins on importing same methods with diff alias)
3+
--FILE--
4+
<?php
5+
6+
trait Trait1
7+
{
8+
public function init()
9+
{
10+
echo("Trait1 - init\n");
11+
}
12+
}
13+
14+
trait Trait2
15+
{
16+
public function init()
17+
{
18+
echo("Trait2 - init\n");
19+
}
20+
}
21+
22+
class Test
23+
{
24+
use Trait1;
25+
26+
use Trait2 {
27+
init as public method1trait2;
28+
}
29+
30+
final public function __construct()
31+
{
32+
$this->init();
33+
$this->method1trait2();
34+
}
35+
}
36+
37+
$test = new Test();
38+
39+
$reflection = new ReflectionClass( $test );
40+
41+
foreach($reflection->getTraitAliases() as $k => $v)
42+
{
43+
echo $k.' => '.$v."\n";
44+
}
45+
?>
46+
--EXPECT--
47+
Trait1 - init
48+
Trait2 - init
49+
method1trait2 => Trait2::init

Zend/tests/traits/error_015.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trait baz {
1414

1515
class bar {
1616
use foo, baz {
17-
baz::test as zzz;
17+
test as zzz;
1818
}
1919
}
2020

Zend/zend_inheritance.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen
11391139
}
11401140
/* }}} */
11411141

1142-
static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_string *key, zend_function *fn, HashTable **overriden) /* {{{ */
1142+
static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_string *key, zend_function *fn, uint32_t is_aliased, HashTable **overriden) /* {{{ */
11431143
{
11441144
zend_function *existing_fn = NULL;
11451145
zend_function *new_fn;
@@ -1191,7 +1191,10 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
11911191
}
11921192
return;
11931193
} else if (UNEXPECTED(existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT)) {
1194-
/* two traits can't define the same non-abstract method */
1194+
/* two traits can't define the same non-abstract method unless they are aliased */
1195+
if (is_aliased) {
1196+
return;
1197+
}
11951198
#if 1
11961199
zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s",
11971200
name, ZSTR_VAL(ce->name));
@@ -1239,6 +1242,7 @@ static int zend_traits_copy_functions(zend_string *fnname, zend_function *fn, ze
12391242
zend_trait_alias *alias, **alias_ptr;
12401243
zend_string *lcname;
12411244
zend_function fn_copy;
1245+
uint32_t is_aliased = 0;
12421246

12431247
/* aliases which are qualified with a class name won't have any ambiguity. method names try to match with alias->trait_names */
12441248
if (ce->trait_aliases) {
@@ -1275,8 +1279,9 @@ static int zend_traits_copy_functions(zend_string *fnname, zend_function *fn, ze
12751279
}
12761280

12771281
lcname = zend_string_tolower(alias->alias);
1278-
zend_add_trait_method(ce, ZSTR_VAL(alias->alias), lcname, &fn_copy, overriden);
1282+
zend_add_trait_method(ce, ZSTR_VAL(alias->alias), lcname, &fn_copy, 0, overriden);
12791283
zend_string_release(lcname);
1284+
is_aliased = 1;
12801285

12811286
/* Record the trait from which this alias was resolved. */
12821287
if (!alias->trait_method->ce) {
@@ -1334,7 +1339,7 @@ static int zend_traits_copy_functions(zend_string *fnname, zend_function *fn, ze
13341339
}
13351340
}
13361341

1337-
zend_add_trait_method(ce, ZSTR_VAL(fn->common.function_name), fnname, &fn_copy, overriden);
1342+
zend_add_trait_method(ce, ZSTR_VAL(fn->common.function_name), fnname, &fn_copy, is_aliased, overriden);
13381343
}
13391344

13401345
return ZEND_HASH_APPLY_KEEP;

0 commit comments

Comments
 (0)