【问题标题】:What's the best way to store PHP class properties? [duplicate]存储 PHP 类属性的最佳方式是什么? [复制]
【发布时间】:2010-10-22 19:17:54
【问题描述】:

重复: 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,还是使用一种方法来设置所有属性和一种方法来获取所有属性?

【问题讨论】:

  • 这是一个很好的问题,但是是的,它是另一个问题的副本。投票结束。

标签: php design-patterns oop class


【解决方案1】:

版本 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"
?>

【讨论】:

  • 你应该使用 public function &__get($member){ 这样你就可以使用 $class->someArray['key'] = 'value';这样你也可以将数组存储为类属性。
【解决方案2】:

我会使用第二个版本当且仅当数据作为一个整体来自外部来源(例如 BD 查询)。在这种情况下,当然建议使用通用__get()/__set() 来访问$this-&gt;data。你也可以考虑实现IteratorAggregate interface返回new ArrayIterator($this-&gt;data)

【讨论】:

    【解决方案3】:

    除非任何一个版本都有真正令人信服的论据(取决于上下文),否则我总是选择让我的 ide/工具提供关于类型、类、关系等的更好信息的格式……直到现在,这是第一种格式.
    还有其他方法可以“类数组”访问数据。

    【讨论】:

      【解决方案4】:

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

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

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

      getter 和 setter 的使用使得调用代码需要更改的属性。并非每个属性都应该是可访问的,因此由定义对象的开发人员决定。显然,getter/setter 模式对公共属性没有意义,但它适用于可能需要一些验证或清理的受保护和私有属性。它们在依赖注入的上下文中也很有意义。

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 这正是我对 getter 和 setter 的问题,它会生成大量无用的代码......
        • @Bryan:如果是这样,您可能应该回到程序代码;)
        【解决方案6】:

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

        除此之外,您的 IDE 不能与 dyn 一起使用。成员,您不能对这些成员使用 PHPDoc,并且 PHPUnit 不能对这些属性使用反射。这简直就是糟糕的编码风格。

        问候, 马里奥

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

            我使用第一个,我在类中使用这个函数来动态地工作:

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

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

            【讨论】:

              猜你喜欢
              • 2012-04-02
              • 2011-08-09
              • 1970-01-01
              • 2018-12-20
              • 2013-06-14
              • 1970-01-01
              • 2011-11-11
              • 1970-01-01
              • 2012-09-21
              相关资源
              最近更新 更多