В последнее время мне стало интересно, есть ли разница между инициализацией переменных, которые имеют значение по умолчанию для Constructor VS в определении класса.
Какой из них лучше, учитывая оптимизацию:
class TestClass { private $test_var = 'Default Value'; function __construct() { } } class TestClass2 { private $test_var; function __construct() { $this->test_var = 'Default Value'; } }
Преимущество инициализации свойств вне конструктора заключается в том, что кто-то, читающий ваш код, сразу узнает его значение по умолчанию.
Неудобным является то, что вы не можете использовать каждый вид данных таким образом – не будет работать с объектными инстанциями, например, или с синтаксисом heredoc, из того, что я помню.
Я не думаю, что есть большая разница, когда дело доходит до производительности – во всяком случае, в вашем приложении, вероятно, много вещей, которые имеют значение намного больше 😉
Тем не менее, исключительно для удовольствия, используя Vulcan Logic Disassembler:
С первым примером кода ( temp-2.php
):
<?php class TestClass { private $test_var = 'Default Value'; function __construct() { } } $a = new TestClass();
Вы получаете эти коды операций:
$ php -d extension=vld.so -d vld.active=1 temp-2.php Branch analysis from position: 0 Return found filename: /home/squale/developpement/tests/temp/temp-2.php function name: (null) number of ops: 11 compiled vars: !0 = $a line # op fetch ext return operands ------------------------------------------------------------------------------- 2 0 EXT_STMT 1 NOP 7 2 EXT_STMT 3 ZEND_FETCH_CLASS :1 'TestClass' 4 EXT_FCALL_BEGIN 5 NEW $2 :1 6 DO_FCALL_BY_NAME 0 7 EXT_FCALL_END 8 ASSIGN !0, $2 9 RETURN 1 10* ZEND_HANDLE_EXCEPTION Class TestClass: Function __construct: Branch analysis from position: 0 Return found filename: /home/squale/developpement/tests/temp/temp-2.php function name: __construct number of ops: 4 compiled vars: none line # op fetch ext return operands ------------------------------------------------------------------------------- 4 0 EXT_NOP 5 1 EXT_STMT 2 RETURN null 3* ZEND_HANDLE_EXCEPTION End of function __construct. End of class TestClass.
Хотя, со вторым примером кода ( temp-3.php
):
<?php class TestClass2 { private $test_var; function __construct() { $this->test_var = 'Default Value'; } } $a = new TestClass2();
Вы получаете эти коды операций:
$ php -d extension=vld.so -d vld.active=1 temp-3.php Branch analysis from position: 0 Return found filename: /home/squale/developpement/tests/temp/temp-3.php function name: (null) number of ops: 11 compiled vars: !0 = $a line # op fetch ext return operands ------------------------------------------------------------------------------- 2 0 EXT_STMT 1 NOP 8 2 EXT_STMT 3 ZEND_FETCH_CLASS :1 'TestClass2' 4 EXT_FCALL_BEGIN 5 NEW $2 :1 6 DO_FCALL_BY_NAME 0 7 EXT_FCALL_END 8 ASSIGN !0, $2 9 9 RETURN 1 10* ZEND_HANDLE_EXCEPTION Class TestClass2: Function __construct: Branch analysis from position: 0 Return found filename: /home/squale/developpement/tests/temp/temp-3.php function name: __construct number of ops: 7 compiled vars: none line # op fetch ext return operands ------------------------------------------------------------------------------- 4 0 EXT_NOP 5 1 EXT_STMT 2 ZEND_ASSIGN_OBJ 'test_var' 3 ZEND_OP_DATA 'Default+Value' 6 4 EXT_STMT 5 RETURN null 6* ZEND_HANDLE_EXCEPTION End of function __construct. End of class TestClass2.
Итак, я предполагаю, что есть какая-то разница … Но не так важно ^^
До вас, чтобы интерпретировать коды операций – но самое смешное, что в первой дампе нет следа « Default Value
» … интересно, на самом деле ^^
Кажется, VLD не может (или просто не делает) сбрасывать все 🙁
Я думаю, что это в основном сводится к личным предпочтениям. Однако есть некоторые значения, которые вы не можете установить непосредственно для переменной, например, экземпляры нового класса, которые необходимо назначить в конструкторе.