Php 跨多个嵌套类传递对象
我遇到了一个问题,当我在不同的类之间传递一个对象,并试图只拥有它的一个实例,而不是多个克隆 TLDR版本: 如果我有对象Php 跨多个嵌套类传递对象,php,Php,我遇到了一个问题,当我在不同的类之间传递一个对象,并试图只拥有它的一个实例,而不是多个克隆 TLDR版本: 如果我有对象A->B->C,其中C在创建时通过B作为参数传递A,那么C->A->B是否会访问创建它的原始B?系统内存中现在有多少份B 更详细的版本: 假设我有一个(可能过于复杂的)嵌套类结构来处理基于服务器的请求。第一步是实例化类会话的对象,然后在其中创建类处理程序的对象$handler。但是,由于$handler需要访问$session的内部属性(以及在其中创建的多个其他对象,如$use
A->B->C
,其中C
在创建时通过B
作为参数传递A
,那么C->A->B
是否会访问创建它的原始B
?系统内存中现在有多少份B
更详细的版本:
假设我有一个(可能过于复杂的)嵌套类结构来处理基于服务器的请求。第一步是实例化类会话
的对象,然后在其中创建类处理程序
的对象$handler
。但是,由于$handler
需要访问$session
的内部属性(以及在其中创建的多个其他对象,如$user
或$database
,其目的应该是自明的),因此我将其作为参数传递:
class Session {
public $handler;
public function __construct() {
$this->handler = new Handler( $this );
//DO STUFF HERE
}
}
处理程序
类继承会话,如下所示:
class Handler {
private $session;
public function __construct( Session $inherited_session ) {
$this->session = $inherited_session;
}
}
旁注:$session
设置为private
,以避免在$this->session->handler->session->handler
种类中出现无限循环
现在,根据我的理解和我所做的所有研究,PHP通过引用传递对象,因此处理程序中的$this->session
对象应该访问系统内存中与原始会话相同的对象?不是复制品吗
但这是我的问题。假设现在我在类仪表板
的处理程序
类中创建了一个第三级嵌套对象,并希望将原始的$session
传递给它(请注意,不只是处理程序
对象本身)。我们开始,所以我们把它放在处理程序
类中的某个地方:
$dashboard = new Dashboard( $this->session );
仪表板
构造函数以与处理程序
完全相同的方式继承会话:
class Dashboard {
private $session;
public function __construct( Session $inherited_session ) {
$this->session = $inherited_session;
}
}
然而,它似乎无法访问调用它的Handler
实例,现在看来我们有多个$session
和$Handler
的副本在浮动,我非常想了解原因,因为它与我所了解的关于引用的所有内容都相矛盾
下面是这种病理行为的一个例子-假设我们在处理程序中有一个变量
:
public $temp_var;
处理程序的构造函数指定一个值:
$this->temp_var = '123';
然后我们尝试从仪表板
类中访问它,作为$this->session->handler->temp\u var
。返回NULL
。为什么?初始化时,$dashboard
是否继承了一个没有可调用的初始化处理程序的$session
副本?如何使每个类只有一个(唯一)对象,并且更新$handler
的内部(公共)变量将正确传递到$dashboard->session->handler
?或者我只是在某个地方犯了一些明显的/愚蠢的错误,却完全看不见
注#1:$session
中设置为$this->var
的任何变量都可以从$dashboard->session->var
正确访问,因此双层嵌套工作正常;这是三级的一级,没有
注意#2:我已经考虑过将$handler
作为参数与$session
一起传递给它的所有嵌套对象(如果不存在解决方案,这就是我必须做的事情),但它并没有解决原始问题,即$this->session->handler
在其嵌套对象中与原始$handler
存在某种莫名其妙的不同
哦,我还要感谢所有读过这一切的人 据我所知,您在这里处理的是组合
而不是继承
因此,您有一个会话
,它被传递给处理程序
,处理程序
和仪表板
都通过组合“知道”会话(保留对私有变量的引用)
我不明白您为什么需要这种循环引用,但是如果您想从仪表板
访问处理程序
,为什么不将处理程序
传递给它呢
除此之外,看起来您正在将处理程序存储在一个局部作用域变量中(我在过去两年中离开了PHP,但是…)
从概念的角度来看,没有“嵌套”,只有引用,所以我认为“三个层次”与此无关
希望有帮助
我修改了Session和privacy只是为了验证$Session仍然是相同的TL;博士…但是…只有你创造的一样多的物体。每个new
创建一个新对象,一个clone
复制一个对象。除非你clone
你的对象,否则你总是会得到一个对它的唯一实例的引用。错误在你的代码中的某个地方,没有你明确告诉PHP这样做,对象就不会被克隆或复制。是的,我也是这么想的,但我今天早上花了4个小时在工作中寻找代码中的错误,却什么也没发现,所以在这里问这个问题只是一种绝望的行为如果你花了这么多时间调试自己的代码,这是一个明确的信号,您需要投资于单元测试,并且您的代码对其开发人员弊大于利(您不应该花费数小时来寻找对象不可用的地方)。这似乎是在创建自己的框架。您是否考虑过使用可用的会话和Dashbo代码
class Session {
public function __construct() {
// isnt $this->handler = new Handler( $this ) ??
$handler = new Handler( $this );
}
}