既然可以在声明变量时设置变量,为什么还要在 PHP 类的构造中设置变量呢?

发布于 2024-12-05 02:53:45 字数 636 浏览 1 评论 0原文

是否有理由在类的构造函数中而不是在声明变量时为变量设置值?我意识到,如果您尝试在声明变量时设置它们,则无法将数据传递到变量中,但是那些始终相同的事物又如何呢(我认为“始终”是一个艰难的主张)?

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();
    }
}

构造函数中的设置值与声明时的设置值相比有哪些优点和缺点?我也对任何与语言无关的方面感到好奇。

Is there a reason to set a value for variables in the constructor of a class rather than when you declare them? I realize you can't pass data into the variables if you try to set them when they are declared, but what about things that will always be the same ( i suppse 'always' is a tough claim to make )?

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

     function __construct() {}
}

as opposed to this:

class variables_set_inside_constructor
{
     private $admin_name;
     private $current_working_directory;

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

What are the advantages and disadvantages of settings values in the constructor versus when they are declared? I'm curious about any language agnostic aspects as well.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

2024-12-12 02:53:45

你的问题有一个错误。这在课堂上不起作用:

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

尝试演示看看什么在这里不起作用。

因此,也许写作的一个(!)原因

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

是因为没有其他选择(自然地,在您在问题中提供的两种选择之间)。这是一种可怕的糟糕做法,没有基于依赖注入和其他技术的精致设计。高级设计抽象 - 或者更准确地说:这使 mysqli 成为 foo 的依赖项 - 包括数据库配置)。

除此之外,请不要使用 var,而是使用 privateprotectedpublic

You have an error in your question. This does not work in a class:

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

Try the Demo to see what does not work here.

So maybe one (!) reason to write

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

is because there is no alternative to it (between the two alternatives you offered in your question only, naturally. This is horrorful bad practice to do so w/o a delicate design based on dependency injection and other high-level design abstractions - or more precise: This is making mysqli a dependency of foo - including the database configuration).

Next to that, please don't use var, use private, protected or public instead.

少女情怀诗 2024-12-12 02:53:45

第一个原因:可重用性。

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

一个很好的示例是在您的开发计算机上以及在您的登台/实时计算机上拥有其他登录信息。这会立即向您展示在构造函数中声明的问题。


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

First reason: re-usability.

Second reason: The credentials for your database connection don't belong in a database class, this should be handled in your application. Your class should only know how to accept and use them - not define them.

A good example case is having other login information on your development machine then on your staging/live machine. This instantly shows you the problem with declaring in the constructor.


I didn't notice what the attempt was until your comment. I'm not used to see var anymore I guess. Luckily I wasn't the only one. Of course declaring like that is impossible.

各空 2024-12-12 02:53:45

您可能会对这篇关于 Java 对象初始值设定项的文章感兴趣。

尽管本文中的许多概念是 Java 特有的,与 PHP 无关,但您可能会发现其中一些有趣的点:

  • 在类中使用属​​性之前,您通常希望将其初始化为某个值(在 PHP 中,这不是一个要求,但在实践中我很少看到违反此准则的情况)。如果您有多个构造函数,那么您必须在每个构造函数中初始化属性,这意味着将进行大量复制和粘贴。 (PHP 也有多个构造函数:)

  • 在 Java 中子类中,默认情况下仅调用“无参数”父构造函数,这意味着您无法保证子类将调用“正确”的构造函数。在 PHP 中,问题变得更加复杂,因为你根本无法保证子类会调用父类的构造函数。直接在父类声明中初始化属性可确保这些属性始终在开始时进行初始化,即使子类构造函数未初始化它们。

You might find this article on Java object initializers to be of some interest.

Although many of the concepts in the article are specific to Java and not relevant to PHP, you might find some of these points interesting:

  • Before you use a property in a class, you generally want it to be initialized to some value (in PHP, this is not a requirement, but in practice I rarely see this guideline violated). If you have multiple constructors then you have to initialize the property in each constructor meaning there will be a lot of copying and pasting. (PHP also has multiple contructors:)

  • In Java subclasses, only the "no-arg" parent constructor is called by default, which means that you can't guarantee that a subclass will call the "correct" constructor. In PHP, the problem is compounded because you can't guarantee that the subclass will call the parent class' constructor at all. Initializing properties directly in the parent class declaration ensures that those properties always start off initialized, even if the subclass constructor doesn't initialize them.

后eg是否自 2024-12-12 02:53:45

为了方便访问。将它们全部声明在一个中心位置可以让您看到所有变量的列表。

如果您在一个单独的项目中,在创建时声明它们,这没什么大不了的。如果您与团队合作,那么遵循一些标准更有意义,这样您就不会感到困惑。

For ease of access. Declaring them all in one central location allows you to, well see a list of all variables.

It's not a big deal if you declare them when it is created if you are on a solo project. If you are working with teams it makes more sense to follow some standard so you don't get confused.

北城半夏 2024-12-12 02:53:45

尽管不灵活,但如果您出于某种原因打算使用类而不创建实例,则在声明变量时设置变量可能会很有用:

class MyClass {
  public $MyVar = 'hello';

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

echo MyClass::MyFunction();

Although not flexible, setting variables when you declare it may be useful if you plan to use a class without creating an instance for some reason:

class MyClass {
  public $MyVar = 'hello';

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

echo MyClass::MyFunction();
若水微香 2024-12-12 02:53:45

它可以帮助从数据库中获取一次记录并重复使用记录。就像我对 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);}
}

it can help to fetch record from database once and reuse records. like i have done with tankauth login library.

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);}
}
梦在深巷 2024-12-12 02:53:45

就我个人而言,我喜欢在构造函数内声明变量,因为这样更容易管理它们。如果我有一个包含大量方法的类,那么找到变量的声明位置将是一件很痛苦的事情,甚至更糟,假设我们收到一个 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;
       }

Personally I like to declared variables inside constructor due its easier to managed them. If I have a class with tons and tons of methods, then it would be a pain in the a** to find where the variable is declared or even worse, let say we are getting a POST request, what could happen if I forget to sanitize and validate this post. SQL injection... If you've all your server request within the constructor you can easily find them all, let say create a method that sanitize depending on what you're expecting and then you'll be secured against those attacks.

example:

 <?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;
       }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文