为什么在声明它们时可以在PHP类的构造中设置变量?

时间:2011-09-16 11:27:03

标签: php oop language-agnostic constructor

是否有理由在类的构造函数中为变量设置值而不是在声明它们时?我知道如果你在声明它们的时候试图设置它们就不能将数据传递给变量,但是那些总是相同的东西(我要求'总是'是一个艰难的主张)?

class variables_set_outside_constructor
{
     private $admin_name = 'jeff';
     private $current_working_directory = get_cwd();

     function __construct() {}
}

与此相反:

class variables_set_inside_constructor
{
     private $admin_name;
     private $current_working_directory;

    function __construct()
    {
         $this->admin_name = 'jeff';
         $this->current_working_directory = get_cwd();
    }
}

构造函数中的设置值与声明它们时的优缺点是什么?我对任何与语言无关的方面都很好奇。

7 个答案:

答案 0 :(得分:3)

您的问题中有错误。这在课堂上不起作用:

class foo
{
   var $mysqli = new mysqli( 'host', 'name', 'pass', 'directory' );
}

尝试使用Demo查看此处不起作用的内容。

所以也许有一个(!)理由写

class foo
{
   var $mysqli;
   public function __construct()
   {
       $this->mysqli = new mysqli( 'host', 'name', 'pass', 'directory' );
   }
}

是因为除了它之外没有其他选择(在您提出的两个备选方案之间,当然也是如此。这是一个非常糟糕的不良做法,没有基于依赖注入和其他高级设计抽象的精致设计 - 或更精确:这使 mysqli 成为 foo 的依赖关系 - 包括数据库配置。)

接下来,请不要使用var,而是使用privateprotectedpublic

答案 1 :(得分:2)

第一个原因:重新使用。

第二个原因:数据库连接的凭据不属于数据库类,应在应用程序中处理。你的班级应该只知道如何接受和使用它们 - 不要定义它们。

一个很好的示例案例是在development machine上,然后在staging/live machine上提供其他登录信息。这会立即显示构造函数中声明的问题。


在你发表评论之前,我没有注意到这是什么尝试。我不习惯再看var了。幸运的是,我不是唯一一个。当然这样宣布是不可能的。

答案 2 :(得分:2)

您可能会发现this article on Java object initializers有一些兴趣。

虽然本文中的许多概念都是针对Java而且与PHP无关,但您可能会发现其中一些内容很有趣:

  • 在类中使用属​​性之前,通常希望将它初始化为某个值(在PHP中,这不是必需的,但在实践中我很少看到违反此指南)。如果你有多个构造函数,那么你必须在每个构造函数中初始化属性,这意味着将有大量的复制和粘贴。 (PHP also has multiple contructors:

  • 在Java子类中,默认情况下只调用“no-arg”父构造函数,这意味着您无法保证子类将调用“正确”的构造函数。在PHP中,问题是复杂的,因为您无法保证子类将完全调用父类的构造函数。直接在父类声明中初始化属性可确保这些属性始终从初始化开始,即使子类构造函数未初始化它们也是如此。

答案 3 :(得分:0)

便于访问。在一个中心位置声明它们可以让你看到所有变量的列表。

如果您在单独项目中创建它们,那么这并不是什么大不了的事。如果您正在与团队合作,那么遵循一些标准会更有意义所以您不需要迷茫。

答案 4 :(得分:0)

虽然不灵活,但如果您因为某些原因计划使用类而不创建实例,则在声明变量时设置变量可能很有用:

class MyClass {
  public $MyVar = 'hello';

  function MyFunction() {
    return self::MyVar;
  }
}

echo MyClass::MyFunction();

答案 5 :(得分:0)

它可以帮助从数据库中获取记录一次并重用记录。就像我已经完成了tankauth登录库。

class Welcome extends CI_Controller{
    public $id;
    function __construct(){
        parent::__construct();
        $this->id = $this->tank_auth->get_user_id();
    }
function index(){ $this->MyModel->get_user($this->id);}
function admin(){ $this->MyModel->get_admin($this->id);}
function profile(){ $this->MyModel->get_profile($this->id);}
}

答案 6 :(得分:0)

我个人喜欢在构造函数中声明变量,因为它更容易管理它们。如果我有一个吨和吨方法的类,那么找到变量声明的位置会更加痛苦,甚至更糟,假设我们正在收到POST请求,如果我忘记了会发生什么清理并验证这篇文章。 SQL注入...如果您在构造函数中提供了所有服务器请求,您可以轻松找到所有这些请求,请创建一个根据您期望的内容进行清理的方法,然后您将获得安全保护反对这些攻击。

示例:

 <?php  
     Class Example extends Core_Controllers 
     {
         private $_var = null;

         public function __construct(){

              if( isset($_POST['number']) ):
                $this->_var = $this->santizeNumber($_POST['number']);
              else:
                 $this->_var = "Not Declared Yet";
              endif;

             $this->methodToCall();
         }
      }


       public function sanitizeNumber($number){
              return filter_var($number, FILTER_SANITIZE_NUM_INT );
       }

       public function methodToCall(){
           echo $this->_var;
       }