在 __construct() 期间切换 类
Switching Classes during __construct()
让我们暂时看看以下 classes:
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
class 而不是 [=14] 重铸用户=].
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
后,在class中设置一个可以用于check/redefinition的标志
$user = new member($id);
if ($user->flag = TRUE) {
$user = new moderator($id);
}
后者感觉像是引入了安全漏洞,特别是因为标志(我猜可能很容易是 $user->user_level
或类似的标志)必须是 public 才能之后再检查。
我 喜欢 做的是只调用 new member($id)
并让它从那里自动处理事情,而不需要之后的 if 语句事实。有办法吗?
您可以通过引入另一个 class(我们称它为 user
)并使用 __call
magic method in php and call_user_func_array
来调用方法。
逻辑是这样的 -
创建一个 user
class 除了 check_user_level
之外没有任何方法。它检查适当的细节并将其 $obj
分配给 member
或 moderator
class.
的实例
这是 classes 的样子(我已经更改了函数来打印一些东西)-
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
class,它会自动确定它是 member
还是 moderator
,如果存在则调用该方法.
//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
*/
让我们暂时看看以下 classes:
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
class 而不是 [=14] 重铸用户=].
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
或类似的标志)必须是 public 才能之后再检查。
我 喜欢 做的是只调用 new member($id)
并让它从那里自动处理事情,而不需要之后的 if 语句事实。有办法吗?
您可以通过引入另一个 class(我们称它为 user
)并使用 __call
magic method in php and call_user_func_array
来调用方法。
逻辑是这样的 -
创建一个 user
class 除了 check_user_level
之外没有任何方法。它检查适当的细节并将其 $obj
分配给 member
或 moderator
class.
的实例
这是 classes 的样子(我已经更改了函数来打印一些东西)-
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
class,它会自动确定它是 member
还是 moderator
,如果存在则调用该方法.
//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
*/