PHP访问父类';s属性,而不创建一个";“子副本”;财产相同

PHP访问父类';s属性,而不创建一个";“子副本”;财产相同,php,class,inheritance,Php,Class,Inheritance,我正在从事一个从过程代码迁移到类体系结构的项目,我遇到了一些我不知道如何解决的问题。请参阅以下代码: // StackOverflow example code # in file classes/parent_class.php class Parent_class { protected $aggregator_array = array(); const TARGET_DATA_LEVEL = 31; // Bit-mask for selecting appropriate ag

我正在从事一个从过程代码迁移到类体系结构的项目,我遇到了一些我不知道如何解决的问题。请参阅以下代码:

// StackOverflow example code
# in file classes/parent_class.php
class Parent_class {
  protected $aggregator_array = array();
  const TARGET_DATA_LEVEL = 31; // Bit-mask for selecting appropriate aggregation level

  public function __construct()
  {
    $this->child_class_1 = new child_class_1();
    $this->child_class_2 = new child_class_2();
  }

  protected function aggregate_data($data_level, $message, $file, $function, $line)
  {
    $add2array = $data_level & self::TARGET_DATA_LEVEL;
    if ($add2array > 0)
    {
      // code to create the array's index, based on current time and other factors
      $this->aggregator_array[$index] = $message;
    }
  }
}

# in file classes/child_class_1.php
class child_class_1 extends Parent_class {
  private function do_something()
  {
    // some code here
    $data_level = 1; // simulate an error of some kind
    $message = 'Foo!';
    $this->aggregate_data($data_level, $message, __FILE__, __FUNCTION__, __LINE__);
  }
}

# in file classes/child_class_1.php
class child_class_2 extends Parent_class {
  private function do_something_else()
  {
    // some code here
    $data_level = 2; // simulate nav message
    $message = 'hello world!';
    $this->aggregate_data($data_level, $message, __FILE__, __FUNCTION__, __LINE__);
  }
}
如您所见,我有一个包含数据聚合方法的父类,以及多个试图访问同一方法以存储消息的子类,以便在脚本运行结束时进行检索。这一切都很好,只是目的(将聚合的消息收集到一个中央数组中)没有实现。所有对聚合\u数据的调用都运行良好,但是来自任何子类的调用都会导致将数据存储到该子类自己的聚合器\u数组中,这不是最佳的。当然,我可以使用array_merge()将子项插入父数组,但是如果我有多个子类(我希望有半打或更多),那么我们谈论的就是一场编码噩梦。我已经尝试过使用静态属性,但这显然不起作用,因为我需要动态更改父数组

所以我的问题是,如何在不创建同名子属性的情况下从子类更改父对象的属性?


现在我非常乐意使用“非相关”类(例如,从当前子类中删除“extensedparent_类”),但问题随后转移到如何访问无关类的属性和方法,我对此一无所知,如果可能的话。

子类对象真的是不同类型的父类对象吗?或者他们只是碰巧与父类交互以便聚合一些东西?基于方法名do_something和do_something,它们实际上不负责这种逻辑除非覆盖/定义特定类型父类的特定行为,例如,如果希望聚合数据()的行为以多态方式更改,则可能不需要扩展父类。

也就是说,访问“不相关”类属性的一种方法是将父类的实例传递到do_*函数中:

// in your main script
$aggregator = new Parent_class();
$thing1->do_something( $aggregator );
$thing2->do_something_else( $aggregator );

// in child_class_1, which you should rename ;-)
private function do_something( $aggregator )
{
    ...
    $aggregator->aggregate_data( $data_level, $message, __FILE__, __FUNCTION__, __LINE__ );
}

// in child_class_2, ditto
private function do_something_else( $aggregator )
{
    ...
    $aggregator->aggregate_data( $data_level, $message, __FILE__, __FUNCTION__, __LINE__ );
}
或者,您可以将父类的实例传递给两个“子”类的构造函数。这样可以减少do_*方法的方法签名的混乱。然后你可以做一些类似的事情:

// main script
$aggregator = new Parent_class();
$thing1 = new child_class_1( $aggregator );
$thing2 = new child_class_2( $aggregator );

// within each of the do_* methods:
$this->$aggregator->aggregate_data( $data_level, $message, __FILE__, __FUNCTION__, __LINE__ );
对于这种方法,请确保您还添加了一个构造函数,用于在“子”类中设置$this->aggregator。

在代码的后面部分,您可以通过调用
$aggregator->GetAggregatorArray
或其他方法来访问“中央阵列”

此外,您没有初始化
$index
,但无论如何都不需要该变量(假设
$aggregator\u array
是一个数字数组)。您只需执行以下操作:

$this->aggregator_array[] = $message;

“子”类实际上并不重写或重新定义“父”类中的任何内容,因此从这个角度来看,不需要扩展“父”类。这似乎是当时获得我所需要的至少部分功能的最佳方式。我将尝试将聚合器方法从基类中分离出来,作为它自己的一个类,首先实例化它,然后尝试将对聚合器的引用发送到其他类,然后看看它是如何工作的。:)我只是测试了一下,效果非常好。非常非常感谢!毕竟我没必要买那箱罗根!:顺便说一句,@acobster,我在前面的评论中没有提到它,但是我在示例代码中有一条评论,关于$index变量是如何基于当前时间创建的,以及其他因素(例如文件、函数{method}和发送消息的行)。:)