【问题标题】:PHP OOP: What am I doing wrong?PHP OOP:我做错了什么?
【发布时间】:2026-01-25 15:15:02
【问题描述】:

我很难理解为什么下面的代码不能按预期工作。我通常使用bucket 依赖注入器,但为了简化,我在下面使用了twittee,结果完全相同。

那么为什么我修改的Config-object(和创建的设置元素)不能用于MockObject-class?据我所知,它被正确传递了。

代码:

$c = new Container();
$c->config = function ($c) { return new Config(); };
$config = $c->config;
$config->setting = 'a value';
$c->MockObject = function ($c) { return new MockObject($c->config); };
$c->MockObject; // Error thrown: `Notice: Undefined index: setting`

类:

class Container {
    protected $s=array();
    function __set($k, $c) { $this->s[$k]=$c; }
    function __get($k) { return $this->s[$k]($this); }
}

class Config {
    public $values = array();
    function __set($key, $value){ $this->values[$key] = $value; }
    function __get($key) { return $this->values[$key]; }    
}

class MockObject {
    function __construct(Config $config) { echo $config->setting; }
}

依赖注入容器由 Fabien Potencier 提供; https://github.com/fabpot/twittee

【问题讨论】:

  • “我在下面使用了 twittee,结果完全相同。”你得到了什么结果?
  • 注意:更强大的 twitee 版本是 Pimple:pimple-project.org 也来自 Fabien Potencier。
  • 是的 - 知道这一点。只是用 twitee 来展示我在这里做什么

标签: php oop dependency-injection


【解决方案1】:

我对 PHP 上的 DI 不是很熟悉,但我认为您的问题出在这一行:

$c->config = function ($c) { return new Config(); };

你原来的代码是

$config = $c->config = function ($c) { return new Config(); };

我猜这在$config->setting = 'a value' 上引发了异常。 $config$c->config 都被定义为一个闭包,它将返回一个新的 Config 对象。由于$config 是一个闭包,它永远不会有setting 属性。

您的更新代码是

$c->config = function ($c) { return new Config(); };  // $c->config is a closure as described
$config = $c->config;  // $config is a new Config object

现在$config 被定义为Config 类,而不是闭包,所以$configure->setting 是有效的。 但是,$c->config 仍然是指返回一个新的 Config 对象的闭包。由于这个新的Config 对象没有名为“Setting”的属性,因此当您尝试检索它时会引发错误。

我不确定它如何与您的其他设计相匹配,但以下内容应该可以按预期工作:

$c->MockObject = function ($c) { return new MockObject($config); };

【讨论】: