Ответ заложен глубоко в том, как работают ссылки в PHP модели - не обязательно в реализации , потому что это может сильно варьироваться, особенно в версиях 5.x. Я уверен, что вы слышали строки, они не похожи на указатели C, или ссылки C ++, и т. Д. И т. Д. В основном, когда переменная назначается или связывается, это может происходить двумя способами - либо по значению (в котором В этом случае новая переменная привязывается к новому «ящику», содержащему копию старого значения), или по ссылке (в этом случае новая переменная привязывается к тому же полю значения, что и старое значение). Это верно, говорим ли мы о переменных, или аргументах функций, или ячейках в массивах.
Когда вы начинаете передавать ссылки в функции, все становится немного странно - очевидно, цель состоит в том, чтобы иметь возможность изменять исходные переменные. Некоторое время назад, передача по ссылке во время вызова (способность передавать ссылку в функцию, которая не ожидала ее появления) устарела, потому что функция, которая не знала, что имеет дело со ссылкой, могла «случайно» изменить вход. Если перейти на другой уровень, если эта функция вызывает вторую функцию, которая сама не ожидала ссылки ... тогда все заканчивается отключением. может работать, но это не гарантировано и может сломаться в некоторых версиях PHP.
Это - то, где call_user_func()
входит. Предположим, вы передаете ссылку (и получаете соответствующее предупреждение о передаче по ссылке во время вызова). Тогда ваша ссылка будет связана с новой переменной - параметрами самого call_user_func()
. Затем, когда вызывается ваша целевая функция, ее параметры не связаны, где вы ожидаете. Они вообще не связаны с исходными параметрами. Они связаны с локальными переменными, которые указаны в объявлении call_user_func()
. call_user_func_array()
тоже требует осторожности. Поместить ссылку в ячейку массива может быть проблемой - поскольку PHP передает этот массив с семантикой «копирование при записи», вы не можете быть уверены, что массив не будет изменен под вами, и копия не получит отделено от оригинальной ссылки.
Самое проницательное объяснение, которое я видел (которое помогло мне сориентироваться в ссылках), было в комментарии к руководству PHP «Передача по ссылке»:
http://ca.php.net/manual/en/language.references.pass.php#99549
В основном логика выглядит следующим образом. Как бы вы написали свою собственную версию call_user_func()
? - а затем объясните, как это ломается со ссылками, и как оно терпит неудачу, когда вы избегаете передачи по ссылке во время вызова Другими словами, правильный способ вызова функций (укажите значение и позвольте PHP решить из объявления функции, передавать ли значение или ссылку) не будет работать при использовании call_user_func()
- вы Вы вызываете две глубокие функции: первую по значению, а вторую по отношению к значениям в первой.
Подумайте об этом, и у вас будет гораздо более глубокое понимание ссылок на PHP (и гораздо более сильная мотивация, если вы сможете избежать ошибок).