如何解决两个Laravel Messenger包之间的Trait方法冲突?
解决两个Laravel Messenger包Trait方法冲突问题
你在同时集成Cmgmyr\Messenger和syntaxlexx/laravel-5-messenger两个Laravel包时,因两个包的Messagable Trait包含同名的messages、threads、participants方法,导致Trait方法冲突报错。
你的代码示例:
namespace App; use Cmgmyr\Messenger\Traits\Messagable; use Lexx\ChatMessenger\Traits\Messagable as chat; class User extends Authenticatable implements HasMedia { use Notifiable; use HasRoles; use HasGroups; use HasPositions; use PivotManger; use InteractsWithMedia; use HasFactory; use Messagable; use chat { chat::messages as chatMessages; chat::threads as chatThreads; chat::participants as chatParticipants; } }
报错信息:
PHP Fatal error: Trait method Lexx\ChatMessenger\Traits\Messagable::messages has not been applied as App\User::messages, because of collision with Cmgmyr\Messenger\Traits\Messagable::messages in /Applications/MAMP/htdocs/plandental/app/User.php on line 20 Symfony\Component\ErrorHandler\Error\FatalError Trait method Lexx\ChatMessenger\Traits\Messagable::messages has not been applied as App\User::messages, because of collision with Cmgmyr\Messenger\Traits\Messagable::messages
解决方案
方案1:保留一个包的原方法名,重命名另一个的冲突方法
如果想保留Cmgmyr\Messenger的原生方法名(messages、threads、participants),同时使用syntaxlexx/laravel-5-messenger的功能,需要明确指定冲突方法的优先级,并重命名后者的方法:
namespace App; // 给两个Trait分别起别名,避免命名混淆 use Cmgmyr\Messenger\Traits\Messagable as BaseMessenger; use Lexx\ChatMessenger\Traits\Messagable as ChatMessenger; class User extends Authenticatable implements HasMedia { use Notifiable; use HasRoles; use HasGroups; use HasPositions; use PivotManger; use InteractsWithMedia; use HasFactory; // 导入基础Messenger Trait use BaseMessenger; // 导入聊天Messenger Trait并处理冲突 use ChatMessenger { // 重命名ChatMessenger的方法 ChatMessenger::messages as chatMessages; ChatMessenger::threads as chatThreads; ChatMessenger::participants as chatParticipants; // 指定优先使用BaseMessenger的原方法,解决冲突 BaseMessenger::messages insteadof ChatMessenger; BaseMessenger::threads insteadof ChatMessenger; BaseMessenger::participants insteadof ChatMessenger; } }
方案2:重命名两个包的所有冲突方法
如果需要同时调用两个包的原生逻辑,且不保留任何一个的原方法名,可以给两个Trait的冲突方法都重命名:
namespace App; use Cmgmyr\Messenger\Traits\Messagable as BaseMessenger; use Lexx\ChatMessenger\Traits\Messagable as ChatMessenger; class User extends Authenticatable implements HasMedia { use Notifiable; use HasRoles; use HasGroups; use HasPositions; use PivotManger; use InteractsWithMedia; use HasFactory; // 重命名BaseMessenger的冲突方法 use BaseMessenger { BaseMessenger::messages as baseMessages; BaseMessenger::threads as baseThreads; BaseMessenger::participants as baseParticipants; } // 重命名ChatMessenger的冲突方法 use ChatMessenger { ChatMessenger::messages as chatMessages; ChatMessenger::threads as chatThreads; ChatMessenger::participants as chatParticipants; } }
修改完成后,两个Trait的方法会以不同名称存在于User类中,不会再出现冲突。
内容的提问来源于stack exchange,提问作者Raquibul Islam
相关产品推荐
相关产品推荐

