【问题标题】:When should I declare variables in a PHP class?什么时候应该在 PHP 类中声明变量?
【发布时间】:2010-11-08 08:38:47
【问题描述】:

我是 OOP 范式的新手,所以这个问题可能有一个简单的解释......

您总是需要在类中声明公共对象范围的变量吗?例如:

<?php

class TestClass
{
    var $declaredVar;

    function __construct()
    {
        $this->declaredVar = "I am a declared variable.";
        $this->undeclaredVar = "I wasn't declared, but I still work.";
    }

    function display()
    {
        echo $this->declaredVar . "<br />";
        echo $this->undeclaredVar;
        echo "<br /><br />"; 
    }
}

$test = new TestClass;
$test->display();

$test->declaredVar = "The declared variable was changed.";
$test->undeclaredVar = "The undeclared variable was changed.";

$test->display();

?>

在这段代码中,即使$declaredVar 是唯一声明的变量,$undeclaredVar 也同样可访问和可用——它似乎就像我已将其声明为公共一样。

如果未声明的类变量总是可以这样访问,那么预先声明它们有什么意义呢?

【问题讨论】:

    标签: php oop


    【解决方案1】:

    一般的 OOP 封装范式说你不应该将你的内部状态变量暴露在外面,这意味着它们应该是私有的,这允许你更改你的类的实现而不需要更改你使用它的代码。最好通过类的构造函数和 getter 和 setter 方法来初始化变量。

    【讨论】:

      【解决方案2】:

      如果你在类中声明一个成员,你可以设置它的可访问性,例如

      private $varname;
      

      【讨论】:

      • 注意:这仅在 PHP 5 之后才被支持(以防你被困在 4.x 树上),但我同意明确设置变量和方法的可见性是一个好习惯- 仅仅因为 PHP 解释器不需要它并不意味着你不应该使用它。
      【解决方案3】:

      那个变量不是未初始化的,它只是未声明。

      在类定义中声明变量是一种可读性风格。 此外,您还可以设置可访问性(私有或公共)。

      无论如何,显式声明变量与 OOP 无关,它是特定于编程语言的。在 Java 中你不能这样做,因为变量必须显式声明。

      【讨论】:

      • 所以只是因为 PHP 真的很宽容,未声明的变量才有效,对吧?
      • 对。不过 PHP 应该发出警告...放置 error_reporting(E_ALL);在文件的顶部。
      • @klez 你关于可访问性风格的两句话相互矛盾:-(
      • 另外,声明变量可以让你的 IDE 提供代码补全。
      • 您是否总是必须在公共/私有变量上使用$this
      【解决方案4】:

      一般来说,一旦你有足够的信息来正确地初始化变量,就应该初始化。

      如果类变量需要合理初始化某些信息,则应将该信息传递给构造函数。

      使用 PHP 的语法在定义点隐式声明变量是,恕我直言,这是引入错误的可靠方法 - 如果您的类需要一个变量,然后声明它,并使用 OOP 提供给您的所有隐藏信息。

      【讨论】:

        【解决方案5】:

        您应该始终声明您的成员变量并在您的类中指定它们的可访问性。我喜欢在我的函数之后把这些信息放在课程的最后。

        您应该在获得足够信息后立即定义它们。可能在构造函数中或通过 setter 函数。

        这样做很重要,因为它使使用您的代码的人的生活更加轻松。他们不必猜测不同的属性来自哪里或它们为什么在那里。此外,大多数(如果不是全部)IDE 不会使用类变量,除非您在某处声明了它们。代码补全/提示是 IDE 的众多优势之一,如果不声明变量,您将使该功能变得无用。

        【讨论】:

        • “你应该在有足够的信息后立即定义它们。”这是在构造函数之前还是在构造函数中还是在setter函数中是否重要?
        【解决方案6】:

        正如 Federico Culloca 所说,“该变量不是未初始化的,它只是未声明的”。此外,您没有为它们定义任何访问修饰符,因此它们的行为类似于应用于它们的公共修饰符。

        您可能已经知道,PHP 是一种松散类型的语言。但是程序员应该始终遵循最佳实践并手动定义访问修饰符。它增加了代码的可读性。

        您可以对类级变量使用 private 修饰符,并在需要时为它们提供访问器和修改器方法(Getters 和 Setters)。

        【讨论】:

          【解决方案7】:

          TLDR:只定义默认/公共中没有的内容

          在类范围内定义或不定义全局变量 - 最终,这是一个设计决策,应该采取以提高代码可读性,仅此而已。 就个人而言,我不“定义所有其中”,我使用默认范围 public(来源:PHP.net -> Visibility)。我会一直这样做,直到我真的需要根据特定需要更改其中的任何一个。

          基本异议

          “但不应该这样设置,以便我们可以根据需要定义 publicprivate 吗?” :如果您需要设置全局变量的状态,请设置它。在您设置之前,它是public。因此,在需要时设置它。不要编写什么都不做的代码,希望在未来的某一天你会感谢自己——很有可能你需要彻底改造你以前所做的一切。如果你有数百个变量都设置为同一个默认实例怎么办?这对任何人有什么帮助?

          为什么要避免硬编码属性的可访问性值?

          在某些时候,我们将能够配置默认值, 然后所有硬编码此类可访问性或该类可访问性的代码都需要重新编程。一般来说,硬编码是不好的,与类属性访问定义相关的大量输入/复制粘贴是不值得的结果。使用默认值。

          风格真的很重要

          如果您的所有类变量都是公开的并且额外的全局定义(可能有 100 个)对您没有帮助,那么请转储它们。但是,如果它们为您的代码提供了结构,那么请保留它们。这样做是为了帮助编码人员,而不是编译器。

          您宁愿修复哪个?

          这个?

          class basicscript extends baseformat {
              public function __construct($args) {
                  $this->startUp($args);
                  
                  return $this;
              }
          }
          

          还是这个?

          class basicscript extends baseformat {
              public $desired_script;
              public $desired_action;
              
              public $object_code;
              public $object_parent;
              public $object_list;
              
              public $script_location;
              public $script_name;
              public $script_file;
              public $script_extension;
              public $script_format;
              public $script_format_lower;
              public $script_args;
              
              public $authentication_object;
              public $cleanser_object;
              public $query_object;
              public $db_access_object;
              public $domain_object;
              public $language_object;
              public $dictionary;
              public $time;
              public $cookie;
              public $formats_object;
              public $version_object;
              public $redirect_object;
          
              public function __construct($args) {
                  $this->startUp($args);
                  
                  return $this;
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2019-05-11
            • 1970-01-01
            • 2011-10-17
            • 1970-01-01
            • 1970-01-01
            • 2014-07-28
            • 1970-01-01
            • 2012-06-10
            • 1970-01-01
            相关资源
            最近更新 更多