Comments 28
Просто не так подробно, и не так понятно (как мне кажется). Эта статья написана чтобы подробно и доступным языком постараться объяснить документацию (даже в тегах поставил документация), чтобы прочитав можно было освежить в памяти забытое, или разобраться в теме если в ней плаваешь.
Видимо вот этот абзац из документации меня сбил
Начиная с PHP 5.6 стало возможным присвоить этим переменным значения, являющиеся результатом выражения, но нельзя использовать для этого функцию, так это вызовет ошибку разбора.
Я ставлю.
Лично мне понравилась доступность изложения и то, как автор раскрывает специфичные моменты.
Вообще я не вижу ничего криминального в разнообразии ленты — можно выбрать что почитать. А вот лично вы, с вашими намеками про недостаток «мотивации/концентрации» на прочтение сложных статей, фактически уже хамите всему сообществу хабра. Лично мне хватает и концентрации и мотивации и прочего на прочтение больших и сложных статей. Когда интересно и полезно.
Честно, так и не понял, что хотел автор донести. Если глянуть на самый первый комментарий, то человек прав.
Ваши 4 характеристики знакомы всем, кто хотя бы раз использовал эти статические свойства в классах.
А если не использовали, то дорога на php.net, а не сюда
В чем-то была замечана аномалия их поведения?
Я не говорию что это неправильное поведение, или ошибочное, именно странное
Вот хотя бы этот пример для меня странный, две функции практически одинаковые (разница в них при беглом, да даже и при внимательном осмотре, не должна повлиять на их поведение), с одинкаовыми параметрами передаными, но возвращают разные результаты.
function staticVarWrong($i)
{
static $var = 0;
static $var = 5;
$var += $i;
var_dump($var);
};
//результат один
staticVarWrong(1); //6
staticVarWrong(5); //11
staticVarWrong(5); //16
function staticVarRight($i)
{
static $var = 0;
static $var = 5;
$var += $i;
static $var = 0; //разница только в этом
var_dump($var);
};
//результат другой
staticVarRight(1); //1
staticVarRight(5); //6
staticVarRight(5); //11
Смысл в том что функции одинаковые по сути, но ведут себя по разному, это мне показалось странным. В документации написано что может быть присвоена однажды, но оказывается есть такой нюанс, про него ничего не написано. Стоит ли про это писать в документации — конечно нет, потому что такое использование неприемлимо. Исчезла ли от этого странность в работе — тоже нет.
При компиляции конструкция static обрабатывается по порядку и последующая инициализация переписывает предыдущую. При выполнении static уже не обрабатывается (можно считать что в райнтайме этих строк уже нет совсем), поэтому, при первом вызове staticVarWrong $var = 5, а в staticVarRight $var = 0;
Именно, нюанс в том, что инициализируется переменная при объявлении функции (условный компайлтайм), при первом require/include или прямом запуске файла, а не при первом вызове функции. Нет никакого счётчика вызовов.
AlexLeonov еще 4 года назад написал исчерпывающую статью на тему static, в которой написано на порядок больше инфы, чем здесь.
Еще страннее при первом вызове staticVar в первой строке она была присвоена, потом во второй строке переприсвоена (но неуспешно), затем с ней было произведено действие сложения, и уже после этого при попытки ее переприсвоить даже в рамках первого вызова функции она вернула уже лежащее в ней значение.
На самом деле все гораздо проще. При декларации переменной с модификатором static
не происходит генерации опкода, а просто создается запись в таблице переменных с ее именем и вычисленным на этапе компиляции значением. Т.е. последнее обработанное компилятором выражение static $var=...
будет определять ее первоначальное значение, а сами строки присвоения в дальнейшей работе программы участвовать не будут.
function fake(){
static $r='qwerty';
$t = 'asdfgh';
}
line #* E I O op fetch ext return operands
---------------------------------------------------------------------------
3 0 E > BIND_STATIC !0, 'r'
4 1 ASSIGN !1, 'asdfgh'
5 2 > RETURN null
Строка 3 — привязываем статическую переменную $r
к области видимости функции.
Строка 4 — присваиваем обычной переменной $t
значение.
Обратите внимание, что присвоение значения переменной $r
в коде отсутствует.
$one = function ($i) {
static $var = 0;
$var += $i;
var_dump($var);
};
$one(1); //1
$one(5); //6
$two = clone($one);
$one(5); //11
$two(5); //11
$two(5); //16
Странные они, статические переменные в PHP