【问题标题】:Handle array of objects in an object处理对象中的对象数组
【发布时间】:2014-12-16 13:44:04
【问题描述】:

鉴于以下两个类,(为了清晰而简单(不对变量进行完整性检查等))

<?php
class Person {
    private $Name;
    private $Phones = [];                // List/array of phone number.

    function __construct($name) { $this->__set('Name',    $name);}

    public function __get($property) {return $this->$property;}
    public function __set($property, $value) {$this->$property = $value;}
}
?>

<?php
class Phone {
    private $Number;
    private $Type;

    public function __construct($number, $type = "private") {
        $this->__set('Number',         $number);
        $this->__set('Type',           $type);
    }

    public function __get($property) {return $this->$property;}
    public function __set($property, $value) {$this->$property = $value;}
}
?>

和“控制器”:

<?php
    include_once("models/person.inc");
    include_once("models/phone.inc");

    $person = new Person('Tony Test');
    $phone0 = new phone("1234567890", "private");
    $phone1 = new phone("9876543210", "work");
    $phone2 = new phone("3216549870");

    $stack          = array($phone0, $phone1, $phone2);

    // assigning the whole array in one big swoop. Very easy, but not smart.
    $person->Phones  = $stack;

    include_once("views/myview.inc");
?>

最后,不重要的观点:

<html>
<head>
<title>person / phone test</title>
</head>
<body>
<table border="1"><tr><td colspan="2">

<?php echo $person->Name; ?></td></tr>

<?php foreach($person->Phones as $val) : ?>
    <tr>
        <td><?php echo $val->Type;   ?></td>
        <td><?php echo $val->Number; ?></td>
    </tr>
<?php endforeach ?>

</table>
<pre><?php echo print_r($person, 1) ?></pre>
</body>
</html>

在 person 对象中处理添加/删除/电话号码的最佳/最合乎逻辑/最智能的方法是什么?如果我按照自己的方式行事,我会让 getter 和 setter 处理它,但是因为它位于对象内部的数组中,所以我对此感到有些困惑。我当然可以为这个属性创建独立的 getter/setter,但其中可能有很多。

我可以做到的一种方法是让__get()__set() 接收整个数组,同时为单个电话对象创建一个特殊的getter 和setter?

我是在朝着正确的方向前进,还是有任何其他方式?

编辑:添加视图。

【问题讨论】:

  • "...但是这些可能有很多。" 我的建议:不要偷懒。每次你因为懒惰而模糊你的代码时,它都会在以后困扰你。
  • 我完全明白你在说什么,但我愿意很努力地偷懒。但是是的...
  • 你应该把__get()__set()留给php,直接在构造函数中使用$this-&gt;name=$name;。就像现在一样,你这样做的方式只是......更长,没有任何好处。 __set() 无论如何都会在你定义你的属性时被 php 调用,所以......是的,我认为你所做的没有意义
  • 此外,请发布您使用的实际代码。在这里,我们可以判断这不是您真正的控制器(或不是您的真正类),因为您尝试在公共范围内分配给私有属性 phone。 (eg$person-&gt;Phones = $stack;) 这个问题贴的代码没有运行;它会引发可见性错误。
  • @FélixGagnon-Grenier 你对构造函数中的__get__set 是错误的。试试this code,你会看到的。这实际上非常重要。关于问题中的代码主题,它有效。我只是没有提供观点,因为我认为这对所提出的问题并不重要。我会添加它,但这对于我的问题并不重要。

标签: php arrays oop object


【解决方案1】:

看看这个:

Best practice: PHP Magic Methods __set and __get

也许魔法方法不是办法。

此外,您可以创建 addPhone、removePhone 等方法。它们会简单地遍历数组并执行其工作或将新手机推送到列表中。

【讨论】:

    【解决方案2】:

    在人员对象中处理添加/删除/电话号码的最佳/最合乎逻辑/最智能的方法是什么?

    我认为这将被它的不同部分封装(正如我所看到的那样)

    收集手机数据

    我假设这是一个简化的示例,您的数据没有硬编码;它来自任何东西,可能是一个数据库,所以你可以随意格式化它,也许是这样的:

    $phoneContainer = array(
      0=>array("1234567890","private"),
      1=>array("9876543210","work"),
      2=>array("3216549870"),
    );
    

    创建对象

    new phone($number,$group); // yeah obviously thanks Felix
    

    ...在迭代容器时

    foreach ($phoneContainer as $phoneInfo) {
      if (isset($phoneInfo[1])) $phone = new phone($phoneInfo[0],$phoneInfo[1]);
      else $phone = new phone($phoneInfo[0]);
      $person->phones[] = $phone;
    }
    

    但是,直接使用公共属性来设置对象数组是有问题的。我至少会考虑person 类中的这样一个属性,它的用法:

    public function addToGroup($group,$what) {
      $this->$group[] = $what;
    }
    // now in the foreach:
    $person->addToGroup('phones',$phone);
    

    您可以使用相同的功能来管理您的所有potentionally many of these 的潜在重要部分,所有这些至少作为容器做出反应。


    不相关,但php has some reserved usage for __set() and __get()。为什么不把它们定义为普通的集合和获取?

    public function get($property) {return $this->$property;}
    public function set($property, $value) {$this->$property = $value;}
    

    它们同样是您自己的函数,您可以根据需要对数据进行清理或验证,但它们也不再是 php 的方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-26
      • 2012-11-22
      • 2015-06-14
      • 2021-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多