2011-11-27 57 views
0

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

虽然这样做,我遇到了一些麻烦与我的数组之一。进一步在一个空白的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); 
    } 
} 
?> 

我从我的实际bot代码中剥离了$ aSettings数组,剩下的就是实验代码。无论如何,代码中的所有内容都基本相同。

如代码所示,test2扩展了测试类。这意味着它应该继承测试的所有公共属性。它确实继承了它..当我给$ aSettings赋值时,问题就开始了。这些改变似乎根本没有任何效果。当$ aSettings ['Other'] ['Time']是var_dump时,它仍然显示它的原始设置值''/ nothing,但setit()方法应该将该值设置为time()。这真的很奇怪:在setit()方法中var_dump'ing $ aSettings ['Other'] ['Time']表明它已经设置为time(),但任何时候它在test2中都是var_dump'd,它显示原始设定值。

我真的不知道是什么原因造成这个..但我需要一个修复,如果我要继续与我的机器人。我已经在Mac,Windows和Linux上的最新PHP版本(5.3.8)上对此进行了测试,所有结果都相同。

回答

0

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

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

  1. test2构造不调用父类的构造(它不能为那将是一个严重的内存泄露,因为对象被创建递归)
  2. 的在test构造创建test2目的从来没有在其上执行的任何操作,以改变$aSettings['Other']['Time']值(即主叫setit()或通过__set()设置属性。
  3. test2一个对象被实例化时,它继承默认的val来自test$aSettings数组的数字。

二是从实例test,这清楚地表明,$aSettings['Other']['Time']被修改为time()创建的对象的后续代码var_dump。

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

http://codepad.org/lsL3mObm

+0

没关系啊,我明白了,那么这是否意味着不是“同步”类之间的变量值,可以这么说? – Blake

+0

正确,他们不是。当你实例化一个对象时,该对象有自己独特的独立变量集合(这些变量称为数据成员)。 – nickb

+0

哈哈,非常感谢您的帮助,这个问题令我很沮丧。我从未想过影响它的新实例。 – Blake