我遇到了一个非常聪明的方法。但我只使用过一次,所以我不记得在哪里找到了实际的片段。
我有一个叫做的课程;
Worksheet {
private $settings
...
funnction GetSettings (){}
...
}
此类具有方法,私有属性,可以从现有类扩展。在运行时,我从类中创建一个对象,“处理它”并将其保存在会话中,以便访问者可以在会话中使用它。在每次请求时,我必须从会话中获取对象,将其反馈给我的处理器,以便更新对象属性(通常由多维数组组成)。
我的Processor类中有一个简单的方法可以创建原始原型并将会话对象安装到原型中。
class Processor {
public function Mount ($worksheetObject){
$this->NewWorksheetPrototype (); //Recreate worksheet from prototype.
require ('includes/mount.php'); //This will go through the provided Object and mount it on to the processor.
}
}
当然我不想遍历整个对象,重新创建可能包含大量多维数组的属性。这样做有可靠的方法吗?我知道我可以做到这一点
$ obj_merged =(object)array_merge((array)$ obj1,(array)$ obj2);
...但这些方法不会合并。
使用附加的方法无法在会话中保存对象?如果这有帮助,我正在Symfony2环境中工作。
答案 0 :(得分:2)
如果你使用的是PHP 5.4或更高版本,你可以尝试这样的事情:
trait MergeableTrait{
protected $mergedObject;
public function merge($object2){
$this->mergedObject;
}
public function __get($name){
if(property_exists($this->mergedObject, $name)){
return $this->mergedObject->{'$name'}; //Pretty sure that's how it works.....
}
throw new RuntimeException("{$name} is not an available property");
}
public function __call($name, $arguments){
if(method_exists($this->mergedObject, $name)){
return call_user_func_array([$this->mergedObject, $name], $arguments);
}
throw new RuntimeException("{$name} is not a callable method");
}
}
我还没有对它进行过测试,但它应该会让你对如何做到这一点有所了解。如果您的具体课程没有定义__call
或__get
方法,您可以像这样添加合并行为:
class Worksheet{
use MergeableTrait;
...
}
......或者您需要的任何地方。
然后你可以这样做:
$ws = new Worksheet();
$proc = new Processor();
$ws->merge($proc);
这未经过测试,我也不建议这样做,因为它会使调试变得更加困难
另请注意,这不会考虑您的方法和属性的可见性。我建议也许扩大检查以包括一些基本的反思,但总的来说,这应该会给你一个良好的开端。