Зачем устанавливать переменные внутри конструкции класса PHP, когда вы можете установить их, когда они объявлены? - PullRequest
9 голосов
/ 16 сентября 2011

Есть ли причина устанавливать значение для переменных в конструкторе класса, а не когда вы их объявляете?Я понимаю, что вы не можете передать данные в переменные, если попытаетесь установить их, когда они объявлены, но как насчет вещей, которые всегда будут одинаковыми (я полагаю, «всегда» - трудное требование)?1002 *

в противоположность этому:

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 ]

3 голосов
/ 16 сентября 2011

У вас есть ошибка в вашем вопросе. Это не работает в классе:

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, используйте private, protected или public вместо.

2 голосов
/ 16 сентября 2011

Возможно, вы найдете эту статью об инициализаторах объектов Java интересной.

Хотя многие из представленных в статье концепций относятся к Java и не относятся к PHP, некоторые из этих моментов могут оказаться интересными:

  • Прежде чем использовать свойство в классе, вы обычно хотите, чтобы оно было инициализировано до некоторого значения (в PHP это не является обязательным требованием, но на практике я редко вижу, как это правило нарушается). Если у вас есть несколько конструкторов, вы должны инициализировать свойство в каждом конструкторе, что означает, что будет много копирования и вставки. ( PHP также имеет несколько конструкторов: )

  • В подклассах Java по умолчанию вызывается только родительский конструктор "no-arg", что означает, что вы не можете гарантировать, что подкласс вызовет "правильный" конструктор. В PHP проблема усложняется, потому что вы не можете гарантировать, что подкласс вызовет конструктор родительского класса вообще. Инициализация свойств непосредственно в объявлении родительского класса гарантирует, что эти свойства всегда начинаются с инициализации, даже если конструктор подкласса не инициализирует их.

2 голосов
/ 16 сентября 2011

Первая причина : возможность повторного использования.

Вторая причина : учетные данные для вашего подключения к базе данных не принадлежат к классу базы данных, это следует обработатьв вашем приложении.Ваш класс должен знать только, как принимать и использовать их, а не определять их.

Хороший пример - наличие другой регистрационной информации на вашем development machine, а затем на staging/live machine.Это сразу показывает вам проблему с объявлением в конструкторе.


Я не заметил, что это была за попытка, до вашего комментария.Я не привык видеть var больше, я думаю.К счастью, я был не единственным.Конечно, объявить подобное невозможно.

0 голосов
/ 25 марта 2016

Лично мне нравится объявлять переменные внутри конструктора, потому что ими легче управлять.Если у меня есть класс с тоннами и тоннами методов, то было бы затруднительно найти в ** место, где объявлена ​​переменная, или даже хуже, скажем, мы получаем запрос 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;
       }
0 голосов
/ 17 октября 2015

это может помочь получить запись из базы данных один раз и повторно использовать записи. как я сделал с библиотекой входа в 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);}
}
0 голосов
/ 16 сентября 2011

Хотя это и не гибко, установка переменных при объявлении может быть полезной, если вы планируете использовать класс, не создавая экземпляр по какой-то причине:

class MyClass {
  public $MyVar = 'hello';

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

echo MyClass::MyFunction();
0 голосов
/ 16 сентября 2011

Для удобства доступа. Объявление их всех в одном центральном месте позволяет вам хорошо видеть список всех переменных.

Это не имеет большого значения, если вы объявляете их при создании, если вы находитесь в сольном проекте. Если вы работаете с командами, имеет больше смысла следовать некоторому стандарту, чтобы вы не получили запутался.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...