PHP - 类属性问题

时间:2011-11-27 03:06:03

标签: php class object

好吧,我完全重新编码了我的高级IRC机器人,允许所有方法和属性在$ this中可用,而不需要像$ this-> Configuration-> someProperty等长链。我的代码被分成几个文件,每个文件都包含自己的类。为此,我使用__set和__get来提供对其他类的这些属性的访问。

在这样做时,我遇到了一个我的阵列的麻烦。在进一步尝试空白的PHP文件后,我确定它必须是PHP错误或意外行为。注意,我没有将问题追溯到__get或__set,这似乎只是扩展的一个问题。

<?php
new test();

class test
{
    public $oInstance;
    public $aSettings = array
    (
        'Bot' => array(),
        'Server' => array(),
        'Logs' => array(),
        'Extensions' => array(),
        'Other' => array('Time' => '')
    );

    public function __construct()
    {
        $this->setit();
        //$this->aSettings['Other']['Time'] = time();
        $this->oInstance = new test2();
    }

    public function setit()
    {
        $this->aSettings['Other'] = time();
    }

    public function __call($sFunction, $aArgs)
    {
        if(method_exists($sValue, $sFunction))
        {
            return call_user_func_array(array($sValue, $sFunction), $aArgs);
        }
    }

    public function __get($sName)
    {
        if(property_exists('test2', $sName))
        {
            return $this->instance->$sName;
        }
    }

    public function __set($sName, $mValue)
    {
        if(property_exists('test2', $sName))
        {
            $this->instance->$sName = $mValue;
            break;
        }
    }
}

class test2 extends test
{
    public function __construct()
    {
        var_dump($this->aSettings);
    }
}
?>

我从我的实际机器人代码中剥离了$ aSettings数组,其余的是实验代码。无论如何,代码中的所有内容基本相同。

如代码所示,test2扩展了测试类。这意味着它应该继承test的所有公共属性。它确实继承了它。当我给$ aSettings赋值时,问题就开始了。这些变化似乎完全没有效果。当$ aSettings ['Other'] ['Time']是var_dump'd时,它仍然显示它的原始设置值''/ nothing,但是setit()方法应该将值设置为time()。这是非常奇怪的事情:在setit()方法中var_dump'ing $ aSettings ['Other'] ['Time']表明它已被设置为time(),但是只要它在test2中是var_dump'd,它就是显示原始设定值。

我真的不知道造成这种情况的原因..但如果我要继续使用我的机器人,我需要修复。我已经在Mac,Windows和Linux上的最新PHP版本(5.3.8)上测试了这一点,所有这些都产生了相同的结果。

1 个答案:

答案 0 :(得分:0)

首先,PHP非常成熟,如果你正在做一些简单的事情(比如在类中操作数组),你可能没有遇到错误,但是做错了。

你必须混淆var_dump输出。您在下面的粘贴中看到的第一个var_dump是因为类test2的构造函数,它在test的构造函数中实例化。此var_dump将始终输出默认值$aSettings['Other']['Time'],因为:

  1. test2的构造函数不会调用父构造函数(因为对象将以递归方式创建,因此不会因此而导致内存泄漏)
  2. test2的构造函数中创建的test的对象从未对其执行任何操作以更改$aSettings['Other']['Time']值(即调用setit()或通过设置属性__set()
  3. 当实例化test2的对象时,它会从$aSettings继承test数组的默认值。
  4. 第二个是通过实例化test创建的对象的var_dump,它清楚地表明$aSettings['Other']['Time']被修改为time()

    请参阅以下粘贴,您会看到来自test类的对象具有$aSettings['Other']['Time']的正确值。

    http://codepad.org/lsL3mObm