让我们来看看以下课程:
class member { public $id; public function __construct($id) { $this->id = $id; // Check user level if ($this->check_user_level() == moderator) { $this = new moderator($this->id); } } private function check_user_level() { // Return user level from system based on user ID } } class moderator extends member { public function show_moderator_tools() { // etc. } } ================== $user = new member($user_id);
所需的行为是让$user
检测用户是否有权获得版主访问权限,如果是,则使用moderator
类而不是member
重新构建用户。
PHP禁止简单地重新分配$this
,因此看起来最好的解决方案是以下之一:
将check_user_level($id)
作为常规函数运行并使用if语句
$user_level = check_user_level($id); if ($user_level == "moderator") { $user = new moderator($id); } else { $user = new member($id); }
在初始化$user
$user = new member($id); if ($user->flag = TRUE) { $user = new moderator($id); }
后者感觉它引入了一个安全漏洞,特别是因为旗帜(可能很容易$user->user_level
或类似的,我猜)必须公开才能检查之后它。
我喜欢做的就是只调用new member($id)
并让它自动处理,而不需要if语句。有没有办法做到这一点?
答案 0 :(得分:1)
您可以通过引入另一个类(让我们称之为user
)并使用php中的__call
魔术方法和call_user_func_array
来调用方法来实现此目的。
逻辑是这样的 -
创建一个除user
之外没有方法的check_user_level
类。它会检查正确的详细信息,并将其$obj
分配给member
或moderator
类的实例。
这是类的外观(我已经改变了函数来打印出来的东西) -
class user{
public function __construct($id) {
$this->id = $id;
if ($this->check_user_level() == "moderator") {
$this->obj = new moderator($this->id);
}else{
$this->obj = new member($this->id);
}
}
public function __call($method, $args){
call_user_func_array(array($this->obj,$method), $args);
}
public function __get($prop){
if(isset($this->obj->$prop)){
return $this->obj->$prop;
}
return NULL;
}
private function check_user_level() {
// Return user level from system based on user ID
if($this->id == 1){
return "moderator";
}
return "member";
}
}
class member {
public $id;
public function __construct($id) {
$this->id = $id;
}
public function show_message($arg){
var_dump($this->id.$arg);
}
}
class moderator extends member{
public function show_moderator_tools() {
var_dump($this->id ."My toolset!");
}
}
所以,现在您只需拨打user
课程即可自动决定是member
还是moderator
并调用该方法(如果存在)。
< / p>
//Trying out a few examples
//Creating a member user
$mem_obj = new user(213);
$mem_obj->show_message("New message");
//Creating a moderator user
$mod_obj = new user(1);
$mod_obj->show_moderator_tools();
/*
OUTPUTS
-------
string(14) "213New message"
string(12) "1My toolset!"
*/
但是你需要小心这些黑客 例如 -
//This will fail
//because mem_obj doesn't have show_moderator_tools()
$mem_obj->show_moderator_tools();
修改强>
您也可以使用__get
继续重定向到属性
我修改了上面的代码,将此方法添加到__call
下。
//Testing it
var_dump($mem_obj->id);
//This is an illegal property
var_dump($mem_obj->illegelProperty);
/*
OUTPUTS
int(213)
NULL
*/