我正在研究一个框架,我试图尽可能强烈地输入. (我在
PHP中工作并从C#中学习了一些我喜欢的想法并试图在这个框架中使用它们.)我正在创建一个Collection类,它是域实体/对象的集合.它有点模仿List< T>之后的模型. .Net中的对象.
我遇到了阻碍我输入这个课程的障碍.如果我有一个UserCollection,它应该只允许User对象进入它.如果我有一个PostCollection,它应该只允许Post对象.
此框架中的所有集合都需要具有某些基本功能,例如添加,删除,迭代.我创建了一个界面,但发现我无法执行以下操作:
interface ICollection { public function add($obj) }
class PostCollection implements ICollection { public function add(Post $obj) {} }
这打破了它对界面的依从性.但我不能强烈键入接口,因为所有集合都是相同的类型.所以我尝试了以下方法:
interface ICollection { public function add($obj) }
abstract class Collection implements ICollection { const type = 'null'; }
class PostCollection extends Collection {
const type = 'Post';
public function add($obj) {
if(!($obj instanceof self::type)) {
throw new UhOhException();
}
}
}
当我尝试运行此代码时,我得到语法错误,意外的T_STRING,期望在instanceof语句上的T_VARIABLE或’$’.对该问题进行了一些研究,看起来原因的根源是$obj instanceof self对于测试类是有效的.似乎PHP不处理表达式中的整个self :: type常量语句.在self :: type变量周围添加括号会引发关于意外'(‘的错误).
一个明显的解决方法是不要使类型变量保持不变.表达式$obj instanceof $this->类型工作正常(如果$type被声明为变量,当然).
我希望有一种方法可以避免这种情况,因为我想将值定义为常量,以避免以后对变量进行任何可能的更改.关于我如何实现这一点的任何想法,或者我在这方面采取PHP的限制?有没有办法“转义”或封装self ::这样PHP在处理时不会死?
更新根据下面的反馈,我想到了一些尝试 – 下面的代码可行!任何人都可以想到1)不这样做的理由,2)这不会最终起作用的原因,或3)更好的方法来解决这个问题?
interface ICollection { public function add($obj) }
abstract class Collection { const type = null; protected $type = self::type; }
class PostCollection extends Collection {
const type = 'Post';
public function add($obj) {
if(!($obj instanceof $this->type)) {
throw new UhOhException();
}
}
}
更新#2:将上面的代码投入生产后,事实证明它不起作用.当我测试它时,我不知道它是如何工作的,但它根本不起作用.我想,我坚持使用受保护的变量.