class Header
{
public function __construct()
{
global $app;
print($app->config);
}
}
class Modules
{
public function __construct()
{
$this->header = new Header();
}
}
class Project
{
public $config = "config";
public function __construct()
{
$this->modules = new Modules();
}
}
$app = new Project();
Run Code Online (Sandbox Code Playgroud)
现在,如果我想从范围内访问根对象(Project类的实例,即)Header,我必须记住我为实例选择的名称(可能会有所不同)并使用global关键字引用它.但我觉得这只是一个快速修复.我需要一种可靠的方法来访问根对象,从中构造当前对象(及其父对象).
换句话说,我需要访问$app内部,$app->modules->header给出名称app本身是可变的事实,链的长度也是动态的.
我可以访问父级的命名空间,parent::但是有类似的东西会很高兴first_ancestor::.
irc*_*ell 12
所以,本着回答问题的精神,当然有办法(警告:这里是龙):
function YouAreAnIdiotIfYouDoThisForReal($skip = 0) {
$bt = debug_backtrace();
if (isset($bt[1]['function']) && $bt[1]['function'] === "__construct") {
// called from constructor, so skip it!
$skip++;
}
foreach ($bt as $stack) {
if (isset($stack['function']) && $stack['function'] === "__construct" && $skip-- <= 0) {
return $stack['object'];
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
可以这样使用:
class Header
{
public function __construct()
{
$this->project = YouAreAnIdiotIfYouDoThisForReal(1);
$this->modules = YouAreAnIdiotIfYouDoThisForReal();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这就是你所要求的.但是,请在任何情况,你应该真正做到这一点.
认真.
我不能强调如果你这样做会有多糟糕.
很脆弱.
而且很脏.
并依赖于调试功能.
和施工顺序之间的硬编码关系.
和其他垃圾.
相反,重构接受显式依赖:
class Header
{
public function __construct(Project $project, Modules $modules)
{
$this->project = $project;
$this->modules = $modules;
}
}
class Modules
{
public function __construct(Project $project)
{
$this->project = $project;
$this->header = new Header($project, $this);
}
}
class Project
{
public $config = "config";
public function __construct()
{
$this->modules = new Modules($this);
}
}
Run Code Online (Sandbox Code Playgroud)
您的依赖关系是明确的,并且一切都清楚地知道发生了什么.
更好的是,完全从等式中删除New:
class Header
{
public function __construct(Project $project)
{
$this->project = $project;
}
}
class Modules
{
public function __construct(Header $header)
{
$this->header = $header;
}
}
class Project
{
public $config = "config";
public function __construct()
{
}
public function setModules(Modules $modules) {
$this->modules = $modules;
}
}
$project = new Project();
$headers = new Header($project);
$modules = new Modules($headers);
$project->setModules($modules);
Run Code Online (Sandbox Code Playgroud)
现在,您的代码本身将完全隔离,而不依赖于任何东西.您可以根据需要覆盖每个依赖项(例如,当您想要将假项目注入时进行测试Header())...
这称为依赖注入.
说真的,不要使用第一种方法.它更像是一个笑话而不是任何东西(展示PHP的力量,但是好主,不,那是邪恶的......
| 归档时间: |
|
| 查看次数: |
243 次 |
| 最近记录: |