【问题标题】:Variable scope problem with super object超级对象的变量范围问题
【发布时间】:2026-01-16 10:10:01
【问题描述】:

我在为我正在处理的框架项目创建“超级对象”(类似于 CodeIgniter)时遇到了一些问题。

我想创建一个超级对象,我的所有其他类都将运行它。我这样做了,但如果不在每个函数中使用 global 关键字,我似乎无法在每个类中使用我的超级对象的对象。

我有这样的事情:

class a
{
    function aa()
    {
        return 'class a';
    }
}

class b
{
    function bb()
    {
        $blah->a->aa();
    }
}

class superobj
{
    function loadClass($class)
    {
        $this->$class = new $class;
    }
}

class blah extends superobj
{
    function __construct()
    {
        $this->loadClass('a');
        $this->loadClass('b');
    }
}

$blah = new $blah;

所以如果我运行它,我会收到一个错误,因为我无法访问 aa 方法。如果我将全局 $blah 放入方法 bb 中,那么它可以工作(或者至少在我的实际项目中可以,我不知道这个 5 秒的模型呵呵)。

那么有什么方法可以使 $blah 对象成为全局对象,这样我就不需要为每个方法都引用它,或者有没有更好的方法来实现我想要做的事情?

我不太擅长 OOP...

【问题讨论】:

标签: php


【解决方案1】:
function bb() {
    $blah->a->aa();
}

确实,与任何函数一样,此函数在其范围内没有变量。 $blah 既没有传递给函数,也没有在函数中定义,所以不存在。

如果您的对象依赖blah 的实例来工作,您应该将它传递给构造函数。

class b {

    var $blah = null;

    function __construct($blah) {
        $this->blah = $blah;
    }

    function bb() {
        $this->blah->foo();
    }
}

$b = new b($instanceOfBlah);

或者,使用静态类来保存对全局对象的引用并根据请求返回它们(注册表模式,如$blah = Registry::get('blah'))。

不要使用global。只是不要。

【讨论】:

  • 有没有办法可以对 blah 的构造函数执行此操作,以便扩展 blah 的每个类都可以自动使用它的方法?
  • @Scott 如果一个类 extends blah,它当然可以像使用它自己的方法一样使用 blah 的方法。
  • 我会试着解释一下,对我来说。如果我通过“superobj”加载“class b”,就像我在上面的示例中所做的那样,我不能使用“class a”的方法。如果我在 superobj 之外加载“class b”,那么它确实有效。但是我需要它能够通过 superobj 加载,所以我只需要为我的所有库使用一个对象。编辑:请注意,在我上面的示例中,我没有扩展 blah,但是在我的实际项目中,例如,调用 $this->a->aa 不起作用。
  • @Scott 抱歉,我不确定您的目标是什么。您可能对 OO 的工作方式有误解。您还谈到了两件不同的事情:扩展对象访问其他对象的方法以及这些对象应该如何传递。也许您可以提供一个更具体的示例来说明您想要实现的目标,使用比“a”和“blah”更有用的名称?
  • 嗯,基本上,我试图解决 PHP 中缺乏多重继承的问题。我想创建一个所有其他类都运行的“主”类,这样我就有一个可以访问所有方法的简单对象。我本质上想要 CodeIgniter 框架的功能。我想也许我将不得不花时间挖掘 CodeIgniter 核心,看看发生了什么。
最近更新 更多