我正在研究一个简单的ORM解决方案,并遇到了棘手的情况.理想情况下,我希望能够在静态上下文和对象上下文中使用方法,具体取决于它的调用方式.我不确定这是否可行,但这就是我的意思:
假设用户模型想静态调用where(),这当前工作正常,例如:
$user = User::where('id = ?', 3);
Run Code Online (Sandbox Code Playgroud)
现在,我也支持关系,例如用户可以拥有消息.建立此关系后,我只需在用户模型中存储消息模型的空白副本并设置外键.例如:
$user -> messages = new Message();
$user -> messages -> foreign_key = 'user_id';
Run Code Online (Sandbox Code Playgroud)
现在,理想情况下,我希望能够致电:
$user -> messages -> where('unread = ?', 1);
Run Code Online (Sandbox Code Playgroud)
在非静态上下文中,在此上下文中使用$ this - > foreign_key,以便仅提取外键与用户id匹配的消息.这种类型的上下文切换在PHP中是否可行?从静态上下文对$ this的任何引用都会抛出一个错误,因为它是一个静态方法,并且不应该依赖于$ this(出于显而易见的原因,当从静态上下文调用时,$ this将不存在)
这有什么巧妙的方法吗?我尝试重载方法有两个不同的原型,有和没有静态关键字,但这引发了重新声明错误.
经过相当多的游戏后,我找到了一种方法,使这个可行,没有Strict Standards@ drew010提到的错误.我不喜欢它,它感觉很糟糕,但它确实有效,所以无论如何我都会发布.
基本想法是让你想访问的方法private和static.然后,您可以定义__call()和__callStatic()魔术方法,以便它们将调用私有静态方法.现在你可能会认为"这不能解决问题,我仍然停留在一个静态的上下文中" - 你只是为了一个小的补充,你可以附加$this到传递给实际方法的参数__call()并获取它作为该方法的最后一个参数.因此,不是$this在对象上下文中引用,而是引用第三个参数来获取对自己实例的引用.
我可能不会很好地解释这个,只看看这段代码:
<?php
class test_class {
private $instanceProperty = 'value';
private static function where ($arg1, $arg2, $obj = NULL) {
if (isset($obj)) {
echo "I'm in an object context ($arg1, $arg2): I can access the instance variable: $obj->instanceProperty<br>\n";
} else {
echo "I'm in a static context ($arg1, $arg2)<br>\n";
}
}
public function __call ($method, $args) {
$method = "self::$method";
if (is_callable($method)) {
$args[] = $this;
return call_user_func_array($method, $args);
}
}
public static function __callStatic ($method, $args) {
$method = "self::$method";
if (is_callable($method)) {
return call_user_func_array($method, $args);
}
}
}
test_class::where('unread = ?', 1);
$obj = new test_class();
$obj->where('unread = ?', 2);
Run Code Online (Sandbox Code Playgroud)