我在跨不同类传递对象并尝试只有一个实例而不是多个克隆时遇到问题。
TLDR版本:
如果我有对象A->B->C
,C
通过A
作为创建参数传递B
,C->A->B
将访问原始{已创建它的{1}}或B
的副本?现在系统内存中有多少B
个副本?
略微更详细的版本:
我们说我有一个(可能过于复杂的)嵌套类结构来处理基于服务器的请求。第一步是实例化类B
的对象,然后在其中创建类Session
的对象$handler
。但是,由于Handler
需要访问$handler
的内部属性(以及在其中创建的多个其他对象,例如$session
或$user
,其目的应该是不言自明),然后我将其作为参数传递:
$database
class Session {
public $handler;
public function __construct() {
$this->handler = new Handler( $this );
//DO STUFF HERE
}
}
类继承了这样的会话:
Handler
旁注:class Handler {
private $session;
public function __construct( Session $inherited_session ) {
$this->session = $inherited_session;
}
}
设置为$session
,以避免private
种类的线条无限循环。
现在,根据我的理解和我所做的所有研究,PHP通过引用传递对象,因此$this->session->handler->session->handler
中的$this->session
对象应该访问同一个对象。系统内存为原始会话?不是自己的副本?
然而,这就是我的问题。假设我现在在类Handler
的{{1}}类中创建了一个第三级嵌套对象,并且希望将原始Handler
传递给它(不是,请注意它,只是Dashboard
1}}对象本身)。我们走了,所以我们将它放在$session
类中的某个位置:
Handler
Handler
构造函数以与 $dashboard = new Dashboard( $this->session );
完全相同的方式继承会话:
Dashboard
但是,它似乎无法访问已调用它的Handler
实例,现在看来我们有class Dashboard {
private $session;
public function __construct( Session $inherited_session ) {
$this->session = $inherited_session;
}
}
和Handler
的多个副本浮动 - 我非常想理解为什么,因为它与我对参考文献的理解相矛盾。
以下是这种病态行为的一个例子 - 假设我们在$session
中有一个变量:
$handler
Handler
的构造函数赋值:
public $temp_var;
然后我们尝试从Handler
类中 $this->temp_var = '123';
访问它。返回Dashboard
。为什么? $this->session->handler->temp_var
是否在初始化时继承了NULL
的副本,但没有初始化的$dashboard
来呼叫?我怎样才能使每个类只有一个(唯一的)对象,更新$session
的内部(公共)变量会被正确地传递给->handler
?或者我只是在某个地方犯了一些明显/愚蠢的错误而完全没有看到它?
注意#1:$handler
中设置为$dashboard->session->handler
的任何变量都可以从$session
正确访问,因此双层嵌套可以按预期工作;它不是三级的。
注意#2:我已经考虑过将$this->var
作为参数传递给所有嵌套对象以及 $dashboard->session->var
(如果没有解决方案的话)存在,这是我必须要做的事情,但它并没有解决$handler
在其嵌套对象中与原始$session
以某种方式和莫名其妙地不同的原始问题。
哦,感谢所有能够全面了解这一切的人!
答案 0 :(得分:0)
据我了解,您在这里处理composition
而不是inheritance
。
所以,你有一个Session
传递给Handler
,Handler
和Dashboard
都知道"知道"通过组合的会话(保持对私有变量的引用)。
我不明白为什么你需要这种循环引用,但如果你想从Handler
访问Dashboard
,为什么不将Handler
传递给它?
除此之外,看起来您将处理程序存储在本地范围的变量中(过去两年我已离开PHP,但是......)
class Session {
public function __construct() {
// isnt $this->handler = new Handler( $this ) ??
$handler = new Handler( $this );
}
}
从概念的角度来看,没有"嵌套"只有引用,所以我不认为"三个层次"与此有关。
希望它有所帮助!
Here's an example我已经修改了会话和隐私,只是为了验证$ session是否仍然相同