PHP: Приоритет при вызове трейтов
Это не совсем статья, а скорее заметка - ответ на вопрос. Итак сам вопрос: есть два трейта с одинаковыми методами, а так же такой же метод в классе использующим этот метод. Что произойдет при попытке запуска такого скрипта..
Пример выглядит так
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24  | 
						<?php trait A {     public function abc(){         echo 'A::abc';     } } trait B {     public function abc(){         echo 'B::abc';     } } class C {     use A,B;      public function abc(){         echo 'C::abc';     } } (new C)->abc();  | 
					
И ответ в данном случае: ошибок не будет, будет вызван метод определенный в классе, т.е. скрипт выведет
| 
					 1 2 3  | 
						C::abc  | 
					
Когда мне задали этот вопрос, я покапался в своих воспоминаниях и точно помнил, что сталкивался с нечто подобным, и тогда мне нужно было все таки указывать какой метод нужно использовать.. странно, мб что-то напутал.. Но, нет, просто у меня была другая ситуация - методы были объявлены только в трейтах, а не в классе:
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21  | 
						<?php trait A {     public function abc(){         echo 'A::abc';     } } trait B {     public function abc(){         echo 'B::abc';     } } class C {     use A,B; } (new C)->abc();  | 
					
приведет к
| 
					 1 2 3  | 
						Fatal error:  Trait method abc has not been applied, because there are collisions with other trait methods on C in [...][...] on line 15  | 
					
и устраняется это именно указанием какой метод будет использоваться, вот так
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  | 
						<?php trait A {     public function abc(){         echo 'A::abc';     } } trait B {     public function abc(){         echo 'B::abc';     } } class C {     use A,B {         A::abc insteadof B;     }  } (new C)->abc();  | 
					
Выведет
| 
					 1 2 3  | 
						A::abc  | 
					
Итак, в подобном случае надо помнить про приоритет вызовов:
- В случае если в классе будет объявлен метод, с таким же именем как в трейтах, то будет использоваться именно он и никаких ошибок не будет
 - В случае, если в классе НЕТ такого метода, а в трейтах есть методы с одинаковыми именами, будет Fatal Error. Устранить его можно указав какой метод надо использовать с помощью ключевого слова insteadof.
 
Вот такая особенность.
Author: | Rating: / | Tags:


Leave a Reply