【问题标题】:PHP Object as propertyPHP 对象作为属性
【发布时间】:2026-01-26 19:05:02
【问题描述】:

图片我想要一个对象 $parent;

例如:

    $parent->firstname = "Firstname";
    $parent->lastname = "Lastname";
    $parent->children = ???

-> 这必须是对象的集合,以便稍后我可以这样做:

    foreach ($parent->children as $child) { 
      $child->firstname
      $child->lastname
    }

这可能吗?

【问题讨论】:

  • $parent->children 应该是一个对象的array。孩子们从哪里来?这会影响您初始化数组的方式。
  • 你真的应该使用 getter 和 setter 方法。不直接将值存储到属性中。

标签: php object


【解决方案1】:

是的,这是可能的,例如,如果您让孩子成为 array

这只是示例,这不是最佳解决方案:

class person
{
    public $firstname = 'Jane';
    public $lastname  = 'Doe';
    public $children  = array();
}

$parent = new person();
$parent->firstname = "Firstname";
$parent->lastname  = "Lastname";

//1st child
$child = new person(); 
$child->firstname = 'aa';
$parent->children[]  = $child;

//2nd child
$child = new person(); 
$child->firstname = 'bb';
$parent->children[]  = $child;        

foreach ($parent->children as $child) {
    ...
}

【讨论】:

    【解决方案2】:

    这取决于你想要什么。由于您的类型只是属性对象,我认为Vahe Shadunts 的解决方案是最轻量级和最简单的。

    如果您想在 PHP 中获得更多控制权,您需要使用 getter 和 setter。这将使您能够使其工作更加具体。

    foreachDocs而言,您的children对象只需实现IteratorIteratorAggregate接口,然后就可以在foreach内部使用(参见Object IterationDocs)。

    这是一个例子:

    $jane = ConcretePerson::build('Jane', 'Lovelock');
    
    $janesChildren = $jane->getChildren();
    $janesChildren->attachPerson(ConcretePerson::build('Clara'));
    $janesChildren->attachPerson(ConcretePerson::build('Alexis'));
    $janesChildren->attachPerson(ConcretePerson::build('Peter'));
    $janesChildren->attachPerson(ConcretePerson::build('Shanti'));
    
    printf(
        "%s %s has the following children (%d):\n",
        $jane->getFirstname(),
        $jane->getLastname(),
        count($jane->getChildren())
    );
    
    foreach($janesChildren as $oneOfJanesChildren)
    {
        echo ' - ', $oneOfJanesChildren->getFirstname(), "\n";
    }
    

    输出:

    Jane Lovelock has the following children (4):
     - Clara
     - Alexis
     - Peter
     - Shanti
    

    如果您需要更多功能(例如随着时间的推移),这些在后台工作的命名接口和对象(我在最后链接代码)与数组和属性相比具有一定的优势。

    假设 Jane 和 Janet 结婚了,所以他们都有相同的孩子,所以他们都有:

    $janet = ConcretePerson::build('Janet', 'Peach');
    $janet->setChildren($janesChildren);
    

    现在珍妮特有了一个新孩子:

    $janet->getChildren()->attachPerson(ConcretePerson::build('Feli'));
    

    Jane 也会自动这样做,因为它们共享同一个子对象。

    但是 PHP 在这些类型化集合方面并不强大,因此您需要一些样板代码来完成这项工作。

    code gist

    【讨论】: