存储PHP类属性的最佳方法是什么?

时间:2009-04-30 09:02:34

标签: php design-patterns oop class

  

重复: What's the best way to store class variables in PHP?

有一段时间以来,我一直在与同事讨论如何在PHP类中存储属性。

那么您认为应该使用哪一个。像这样:

Class test{
    public $attr1;
    public $attr2;
    .............. 
    public function __construct(){
        $this->attr1 = val;  
        $this->attr1 = val;
        ...................   
    }
}

对战:

Class test{
    public $data;

    public function __construct(){
        $this->data['attr1'] = val;
        $this->data['attr2'] = val;
        ..........................       
    }
}

当您拥有必须经常存储和检索的许多属性的对象时,这很重要。

在处理具有许多属性的对象时,同样重要的是,您是为每个属性使用getter和setter,还是使用一个方法来设置all和one方法来获取所有属性?

8 个答案:

答案 0 :(得分:9)

版本1是更“经典”的做事方式。你的对象与你说的完全一样。

我不能说哪个是严格“更好”,但我可以说哪个更方便。

我已经使用第二个版本(通常用于CodeIgniter中的数据库模型,特别是在早期开发期间)与自定义PHP5 getter和setter方法结合使用,以允许您动态地重载类。即

<?php
    class foo{
        private $data = array();

        function __construct()
        {
            # code...
        }

        public function __get($member) {
            if (isset($this->data[$member])) {
                return $this->data[$member];
            }
        }

        public function __set($member, $value) {
            // The ID of the dataset is read-only
            if ($member == "id") {
                return;
            }
            if (isset($this->data[$member])) {
                $this->data[$member] = $value;
            }
        }
    }

    $bar = new foo()
    $bar->propertyDoesntExist = "this is a test";
    echo $bar->propertyDoesntExist; //outputs "this is a test"
?>

答案 1 :(得分:5)

当且仅当数据来自外部源(例如BD查询)时,我才会使用第二个版本。在这种情况下,当然建议使用通用__get()/__set()来访问$this->data。您也可以考虑实施IteratorAggregate interface返回new ArrayIterator($this->data)

答案 2 :(得分:1)

除非两个版本都有令人信服的论据(在上下文中展开),否则我总是选择格式,让我的ide / tools提供有关类型,类,关系等的更好信息......直到现在,这是第一种格式。
还有其他方法可以访问“类似数组”的数据。

答案 3 :(得分:1)

第一种方法非常标准。它清楚地定义了属性,并允许IDE和代码文档工具获取可用的对象属性。

第二种方法非常适用于需要将数据保存在单独范围内的受保护和私有级属性。我在各种模型类中使用这两种方法的组合,或跟踪配置选项和默认值。但是,我总是预先填充这些数组,并确保严格遵守其中的数据。

我不会主张将第二种方法用于公共属性,因为它表明缺乏对对象属性和变量范围的理解,并且可能在代码中引入问题(如果有人用字符串覆盖该根数组会怎样? )

使用getter和setter会使得需要可以更改为调用代码的属性。并非每个属性都可以访问,因此由开发人员定义对象。显然,getter / setter模式对公共属性没有意义,但它与受保护和私有属性有关,可能需要进行一些验证或进行清理。它们在依赖注入的背景下也有意义。

答案 4 :(得分:0)

我个人使用版本1,因为我认为它更正确,支持IDE中的自动完成并使调试更容易。

我还使用几乎所有成员变量的getter和setter(我在大多数时间定义private / protected),因为设置一个值会经常触发其他值的更改。创建g&amp; s的一个缺点是随着时间的推移积累的大量丑陋,愚蠢的代码,如果你定义getters / setter,即使是那些不会在其他地方触发更改的属性。我仍然为一致的界面做这件事 - 我不知道什么时候我会引入额外的功能或错误修正,引入更多的设置更改。

答案 5 :(得分:0)

我也更喜欢版本1。如果您不需要动态成员(Chris提供的版本),您应该定义您的成员。在大多数情况下,动态方式导致一个可怕的结构,使得很难理解你的代码。想象一下,有人可能需要调试你的代码并且不知道你的代码^^。我们有一个更大的项目,它使用动态成员来镜像db表中的字段。在不知道桌子的情况下很难使用它。

除此之外,您的IDE无法使用dyn。成员,你不能使用PHPDoc为那些成员和PHPUnit不能对这些属性使用Reflection。这简直就是糟糕的编码风格。

此致 马里奥

答案 6 :(得分:0)

使用版本1的原因是版本2发生在对象中。您的对象已经是值的值的映射。通过添加自己的数组映射,您将添加一个不必要的间接级别。

答案 7 :(得分:0)

最好的方法是确保标准的,但第二种肯定更舒服....

我使用第一个,我在课堂上使用这个函数来做作用:

    public function GET__Attributes_in_Array(){
     $Prova = get_class_vars(get_class($this));
     print_r($Prova);

     return $Prova;
}

此函数返回一个包含类的所有属性和值的数组...