我马上开始。我有一个类 User
需要执行一些数据库操作(使用类 DB
)。 Controller 根据需要创建 DB
,并使用其构造函数将其注入(inject)到 User
中。
当用户登录时,User
对象被存储到 session 中。问题是DB
无法序列化到session,所以当User
醒来时,它的db
成员是null
,这很糟糕。我很简单地解决了这个问题
public function __wakeup() { $this->db = new DB; }
..然而,这绝对违反了 DI,如果 DB
需要根据 Controller 而不同( Controller 创建 DB
毕竟它需要)。
问题是当 User
从 session 中反序列化时,它不会再次构造,因此它没有机会获得 DB 成员。我有几个可能的解决方案,每个问题都有:
- 允许通过 setter 注入(inject)设置数据库
- 这似乎也不是一个很好的解决方案。它还打开了在不适当的时间设置
DB
的可能性,并且似乎仍然违反了 DI 精神。 Controller 还必须知道设置DB
- 这似乎也不是一个很好的解决方案。它还打开了在不适当的时间设置
- 不序列化对象,而是序列化一个token,每次都重新创建对象
- 这会很不方便而且看起来效率低下。这也可能导致一些重复(每个 Controller 都需要执行类似
$usr = new User($_SESSION['user-token'], new DB);
的操作)。另一方面,将User
对象排除在 superglobals 之外会阻止一些讨厌的全局变量使用。
- 这会很不方便而且看起来效率低下。这也可能导致一些重复(每个 Controller 都需要执行类似
有什么建议吗?
最佳答案
由于您的用户对象依赖于数据库对象,并且数据库对象无法序列化,因此您的用户对象本身也无法序列化。
所以基本上你的问题是你序列化了一个不可序列化的对象。
您真正需要的是 session 状态。创建一个能够选择模型(设置)并能够提供模型(获取)的 session 状态对象。
通过向 session 对象添加如何序列化特定对象的逻辑(或更好:存储在 session 中,例如,如果它是数据库模型,您通常只需要存储 ID)这将像任何其他工厂一样工作。
然后将 Session 对象作为依赖注入(inject)。
关于php - 依赖注入(inject)和序列化类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8838716/