【问题标题】:Add elements to array that is an object property将元素添加到作为对象属性的数组
【发布时间】:2023-04-01 16:19:01
【问题描述】:

假设我有这些课程:

abstract class AbstractEntity {
    function __construct($args = array()) {
        foreach ($args as $property => $value) {
            $this->{$property} = $value;
        }
    }

    public function __get( $property ) {
        if( isset( $this->{$property} ) ) {
            return $this->{$property};
        } else {
           throw new \Exception( 'Porperty ' . $property . ' not found!' );
        }
    }
    public function __set($property, $value) {
        if( isset( $this->{$property} ) ) {
            $this->{$property} = $value;
        } else {
            throw new \Exception( 'Porperty ' . $property . ' not found!' );
        }
    }
}

class Person extends AbstractEntity {
    protected $name;
}

class Group extends AbstractEntity  {
    protected $people; // array of Person
}

现在我想在循环中使用Person 对象填充$people 属性,例如:

$group = new Group( array( 'people' => array() ) );

foreach ( get_people_data() as $person_data ) {
    $group->people[] = new Person( $person_data['name'] );
}

但这不起作用,我得到一个错误:

Notice: Indirect modification of overloaded property Group::$people has no effect in ...

我知道我可以使用临时数组,用Person 对象填充它,然后将其分配给$people 属性,但我有点不喜欢它......那么,还有其他解决方案吗?

【问题讨论】:

  • 发布更多class Group。它是否实现了魔术__get()?它应该是隐含的,但如果你声明public $people = array(); 有什么改变吗? (我不希望它)
  • @MichaelBerkowski,查看编辑后的代码,我试图总结,但我摆脱了重要的部分......
  • 阅读property visibility。你没有声明,但属性应该是public
  • @MichaelBerkowski,我的实际上受到保护,将它们公开是一种好习惯吗?我一直被告知这不是……或者那只发生在 Java 中??
  • 好吧,如果他们是protected,你就不能在课堂之外(比如在你的循环中)访问它们,这就是你问题的根源。如果您需要在课堂外附加到$group->people[],它们需要是公开的

标签: php arrays object properties


【解决方案1】:

尝试公开 $people 属性。它适用于我的情况。

[...]
public $people = array(); // array of Person
[...]

$group->people[] = new Person( 1);
$group->people[] = new Person( 2);

【讨论】:

  • 然后使用setter/getter。或者像 addPerson(); 这样的方法
【解决方案2】:

你的代码似乎有点不完整,这是我的假设,看看它是怎么回事......

<?php

class Person {
    public $name;
    function __construct($n)
    {
        $this->name=$n;
    }
}

class Group {
public $people = array(); // array of Person
}

$arr = [0=>['name'=>'John'],1=>['name'=>'Jack'],2=>['name'=>'Jill']];
$group = new Group();
foreach ($arr as $person_data ) {
    $group->people[] = new Person( $person_data['name'] );
}
print_r($group->people);

OUTPUT :

Array
(
    [0] => Person Object
        (
            [name] => John
        )

    [1] => Person Object
        (
            [name] => Jack
        )

    [2] => Person Object
        (
            [name] => Jill
        )

)

【讨论】:

  • 你知道protectedprivate成员不能在课堂外访问吗?
  • 好吧,我宁愿说 protectedprivate 属性不能直接在类之外访问,但只能使用 getter 和 setter 方法,就像我在我的 AbstractEntity 类中,GroupPerson 继承自......对吗?
【解决方案3】:

最终我在AbstractEntity 类中添加了一个函数,该函数允许将$value 添加到该类的$property 中,该类必须是array

public function append_to( $property, $value ) {

    // Check that $property exists on the object and is an array
    if( isset( $this->{$property} ) && is_array( $this->{$property} ) ) {

        $this->{$property}[] = $value;

    } else {

        throw new \Exception( 'Porperty ' . $property . ' not found or is not array!' );
    }
}

与此处评论的其他方法相比,这些方法有一些好处(在我看来):

  1. 我不需要填写任何字段public
  2. 我不必创建像addPerson() 这样的函数,因此我可以将所有扩展AbstractEntity 的类保留为一组简单的属性,而无需任何函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 2021-03-22
    • 2015-07-01
    • 2019-12-27
    • 2020-08-09
    • 1970-01-01
    相关资源
    最近更新 更多