我想知道是否可以封装类的方法,但是然后在消费类中公开它们。例如(JFTR,我知道这段代码是错误的)
class Consumer{
public function __construct($obj){
$this->obj = $obj;
}
public function doCommand(){
$this->obj->command();
}
}
class Consumed{
//I would make the constructor private, but to save space...
public function __construct(){}
private function command(){
echo "Executing command in the context of the Consumer";
}
}
$consumer = new Consumer(new Consumed);
$consumer->doCommand();
//just to reiterate, I know this throws an error
最终,我希望能够创建无法在单个控制类的上下文之外直接引用的组件。
答案 0 :(得分:1)
您可以模仿与__call和debug_backtrace类似的内容。
<?php
class Consumer{
public function __construct($obj){
$this->obj = $obj;
}
public function doCommand(){
$this->obj->command();
}
}
class Consumed {
// classes that are aloowed to call private functions
private $friends = array('Consumer');
public function __construct(){}
private function command() {
echo "Executing command in the context of the Consumer. \n";
}
public function __call($name, $arguments) {
$dt = debug_backtrace();
// [0] describes this method's frame
// [1] is the would-be frame of the method command()
// [2] is the frame of the direct caller. That's the interesting one.
if ( isset($dt[2], $dt[2]['class']) && in_array($dt[2]['class'], $this->friends) ) {
return call_user_func_array(array($this,$name), $arguments);
}
else {
die('!__call()');
}
}
}
$c = new Consumed;
$consumer = new Consumer($c);
$consumer->doCommand();
echo 'and now without Consumer: ';
$c->command();
打印
Executing command in the context of the Consumer.
and now without Consumer: !__call()
答案 1 :(得分:0)
当然可以,只需制作这些方法protected
,而不是private
并Consumed
从Consumer
延伸。我不确定这些好处。