更新: 在我思考这个问题的过程中,发现我并不孤单,实际上这似乎是一个bug。请参见此处。它被修复的那一天将会是美好的一天!:)
一开始我的想法是“我喜欢PHP traits!我要无处不用它们!^_^”,但现在这已经成为了一个“思考练习/学习体验 >_<”。
考虑以下例子:
trait TheErrorOfYourWays{
public function booboo(){
echo 'You had a booboo :(';
}
}
trait SpectacularStuff1 {
use TheErrorOfYourWays;
}
trait SpectacularStuff2 {
use TheErrorOfYourWays;
}
class DoSomethingSpectacular {
use SpectacularStuff1, SpectacularStuff2;
}
这导致一个(显然不太显然的)错误:
致命错误:因为在DoSomethingSpectacular上有与其他trait方法冲突,所以未应用booboo trait方法。
我的问题是:如何解决traits中的方法冲突?是否可以实现重叠的trait“继承”?如果可以,正确的方法是什么?
我为什么要这样做:
- 我想创建自包含的traits和类(混合和匹配风格)。 如果可能的话,我想说“使用”,然后必须发生魔法。不需要抓头想,“这个trait在哪个命名空间中?”等等。
- 当我做一些“冒险”并发现我无意中创建了冲突时,不需要在代码中即时修改类和traits。
- 看起来好像是个好主意。
我尝试过的方法:
- PHP手册。
- Google搜索。
- 在SO上查找,包括这个问题 -> 不适用于此情况的答案。
- 找到了这个,但我正在使用PHP版本5.5.1。已修复,对吗?对吗?
在不同的位置、时间、宇宙中使用“as”、“alias”甚至是“insteadof”的奇妙组合,包括但不限于:
trait SpectacularStuff1 { use TheErrorOfYourWays{ TheErrorOfYourWays::booboo as booboo1; } } trait SpectacularStuff2 { use TheErrorOfYourWays{ TheErrorOfYourWays::booboo as booboo2; } } class DoSomethingSpectacular { use SpectacularStuff1, SpectacularStuff2 { /* Tried separately, but included here for brevity's sake */ SpectacularStuff1::booboo as booboo3; SpectacularStuff2::booboo as booboo4; } }
与
use TheErrorOfYourWays as Erroneous1; trait SpectacularStuff1 { use Erroneous1{ Erroneous1::booboo as booboo1; } } use TheErrorOfYourWays as Erroneous2; trait SpectacularStuff2 { use Erroneous2{ Erroneous2::booboo as booboo2; } }
我明白:
- 我可以将TheErrorOfYourWays更改为类并使booboo()静态化,但我想了解这种特定的trait行为。
- 我可以从traits中删除TheErrorOfYourWays并在类中使用它,但那几乎不是“自包含”的。每次我使用traits时,我都必须记得在类中使用TheErrorOfYourWays,即使我没有直接从类中调用booboo()。听起来很危险。
- 我可能犯了一些新手语法错误或者在别名方面理解有误。如果是这样,请……慢慢地解释一下……
- 可能有更好的方法来解决这个问题。如果是这样,请……慢慢地解释一下……
- 我可能过早地热情了,PHP目前还不能实现这个。请温柔地让我意识到这一点。
谢谢!