call_user_func_array против call_user_func

Я столкнулся с интересной проблемой сегодня. У нас есть приложение, которое использует функциональность кэширования Zend Frameworks. Запрос к этому приложению обычно вызывает метод фабрики, используя следующую строку

$result =  call_user_func_array(array("myclass", "factory"), array($id));

Идея состоит в том, чтобы вернуть объект из фабричного метода, к которому мы можем получить доступ позже. Когда мы реализовали функцию кэширования, этот вызов просто умирает. Никаких ошибок, только белый экран. Ничего в журнале ошибок. Мы можем записать строку ошибки до того, как все будет в порядке, но попытка error_log внутри фабричного метода ничего не даст

Интересно, что изменив строку на:

$result =  call_user_func(array("myclass", "factory"), $id);

устраняет проблему

Мы потратили несколько часов, просматривая сообщения об ошибках, и не смогли придумать много, чтобы объяснить это поведение. Мысли кто-нибудь?

 Alexander Trauzzi10 авг. 2010 г., 16:37
Я заметил эту проблему совсем недавно, когда преобразовывал весь мой код в пространства имен. Класс существует нормально, и я могу создать его экземпляры. Но когда я беру экземпляр и пытаюсь вызвать для него метод, используя _array или нет, ничего не происходит. Код продолжается, но метод, кажется, никогда не вызывается.

Ответы на вопрос(3)

Решение Вопроса

У меня были такие проблемы, которые сводились к тому, что __autoload не запускается должным образом, когда еще не загруженный класс был вызван с помощью команды PHP. Насколько мне известно, никакой другой стратегии, кроме глупых проб и ошибок, просто попробуйте, если строка явно вызывает класс, прежде чем команда PHP решит это за вас.

$dummy = new MyClassName;
call_user_func_array(array('MyClassName', 'method'), array($id));
unset($dummy);
 goose7715 июл. 2009 г., 16:07
Моя теория гласит, что call_user_func_array становится немного более безрассудным (из-за отсутствия лучшего термина) при попытке сделать вызов. Было бы интересно увидеть источник двух функций, чтобы сравнить их. Я собираюсь отправить отчет об ошибке в PHP для этой проблемы и посмотреть, что они говорят.
 23 июл. 2009 г., 06:18
призвание__autoload напрямую или хотя быclass_exists (со вторым параметром true, который используется по умолчанию) будет более дешевым способом запуска автозагрузчика. Таким образом, вы не тратите впустую память на создание экземпляра класса.

Это сегфолтинг? Проверьте свой «корень» Логи apache (вне любого виртуального хоста) и видят, что происходит. Если этот поток является segfaulting, вы можете сохранить это в списках рассылки PHP и / или трекере ошибок.

В качестве альтернативы вы можете попробовать запустить http в однопользовательском режиме, в GDB, с помощью отладочной компиляции php и посмотреть, сможете ли вы его перехватить, но это большая работа :-)

 goose7714 июл. 2009 г., 03:56
Подожди ... проверь что ... это был Сегфолт. Прочь в PHP я иду.
 goose7713 июл. 2009 г., 20:54
Я проверил все свои журналы, и нет никаких признаков того, что Apache является segfaulting. Я хотел бы иметь время для отладки Apache в однопользовательском режиме.
 14 июл. 2009 г., 22:56
Я столкнулся с некоторыми сложностями в отладке ошибок в PHP при использовании автозагрузки для моих классов. По существу, некоторые функции не запускают автозагрузчик, если класс не существует, даже не генерируют фатальную ошибку и продолжают безрассудное прекращение. Хорошим примером является использование method_exists () со строкой, представляющей имя класса, которое еще не было включено == segfault.

Какую версию php вы используете? Была проблема в объединенииcall_user_func_array сReflectionClass в одной точке. Я не уверен, что это исправлено.

 goose7713 июл. 2009 г., 19:52
мы используем 5.2.8
 13 июл. 2009 г., 22:00
Я почти уверен, что проблема, о которой я говорю, более старая, чем эта.

Ваш ответ на вопрос