1--TEST-- 2Bug #69180: Backtrace does not honor trait conflict resolution / method aliasing 3--FILE-- 4<?php 5 6trait T { 7 public function __get($name): string { 8 var_dump(__METHOD__); 9 print_r(array_map(fn ($v) => $v['class'] . '::' . $v['function'], debug_backtrace())); 10 11 return '=' . $name; 12 } 13} 14 15class Model { 16 use T { 17 T::__get as private __t_get; 18 } 19 20 public function __get($name): string { 21 var_dump(__METHOD__); 22 return $this->__t_get($name); 23 } 24} 25 26class X extends Model {} 27 28class Y extends Model { 29 public function __get($name): string { 30 var_dump(__METHOD__); 31 return parent::__get($name); 32 } 33} 34 35class Z extends Model { 36 private function __x_get($name): string { 37 var_dump(__METHOD__); 38 return parent::__get($name); 39 } 40 41 public function __get($name): string { 42 var_dump(__METHOD__); 43 return $this->__x_get($name); 44 } 45} 46 47class P extends Model { 48 private function __t_get($name): string { 49 var_dump(__METHOD__); 50 return parent::__get($name); 51 } 52 53 public function __get($name): string { 54 var_dump(__METHOD__); 55 return $this->__t_get($name); 56 } 57} 58 59$m = new X(); 60$m->a; 61 62echo "\n"; 63 64$m = new Y(); 65$m->a; 66 67echo "\n"; 68 69$m = new Z(); 70$m->a; 71 72echo "\n"; 73 74$m = new P(); 75$m->a; 76 77?> 78--EXPECT-- 79string(12) "Model::__get" 80string(8) "T::__get" 81Array 82( 83 [0] => Model::__t_get 84 [1] => Model::__get 85) 86 87string(8) "Y::__get" 88string(12) "Model::__get" 89string(8) "T::__get" 90Array 91( 92 [0] => Model::__t_get 93 [1] => Model::__get 94 [2] => Y::__get 95) 96 97string(8) "Z::__get" 98string(10) "Z::__x_get" 99string(12) "Model::__get" 100string(8) "T::__get" 101Array 102( 103 [0] => Model::__t_get 104 [1] => Model::__get 105 [2] => Z::__x_get 106 [3] => Z::__get 107) 108 109string(8) "P::__get" 110string(10) "P::__t_get" 111string(12) "Model::__get" 112string(8) "T::__get" 113Array 114( 115 [0] => Model::__t_get 116 [1] => Model::__get 117 [2] => P::__t_get 118 [3] => P::__get 119) 120