Итак, у меня очень странная проблема.
Во-первых, я использую PHP 5.2.6 (как часть MAMP, хотя это также происходит на сервере LAMP с 5.2.6), пишу веб-сайт с помощью Zend Framework 1.7.2.
Во-вторых, программное обеспечение, которое я пишу, выполняет довольно сложные статистические расчеты, требующие большого объема памяти. Обычно он работает нормально, если в качестве ограничения памяти установлено 128 МБ.
Итак, самое интересное.
У меня есть класс, который отвечает исключительно за получение необходимых ему данных, выполнение необходимых вычислений, а затем за возврат значений. После его запуска я отключил его, так как PHP, кажется, думает, что он все еще находится в области видимости и удерживает для него память, несмотря на завершение функции, в которой он вызывается (это вызывало проблемы, когда второй запуск вычисления был достиг предела памяти, и скрипт умер). После того, как это вычисление выполняется один раз внутри этой функции, оно снова запускается в другой функции, чтобы выполнить другое вычисление (это происходит во время того же запуска выполнения). Вот где все становится странно.
Если я запущу это второе вычисление, вызывающая функция запустится снова, несмотря на то, что нет абсолютно никаких вызовов этой функции из кода, который выполняет это вычисление. Кроме того, в PHP не появляются ошибки или предупреждения.
Однако, если я увеличу лимит памяти (скажем, до 1024 МБ), этого не произойдет. Общая вызывающая функция запускается один раз и продолжает свой веселый путь.
Итак, позвольте мне нарисовать карту ниже.
function A{
calls function B
calls function D
}
function B{
calls calculation function C
}
function D{
calls calculation function C
}
при 128 МБ памяти путь функций следующий (в и обратно к вызывающему): A->B->C->B->A->D->C->D->затем он запускает A из начало функции по какой-то причине до конца (есть условный случай, который становится истинным во время этого пути выполнения, поэтому путь не повторяется)
с 1 ГБ памяти путь функций следующий: A->B->C->B->A->D->C->D->конец A, что и должно произойти.
Если я уберу второй расчет из функции D, он сработает. Если я увеличу лимит памяти, это сработает.
Вопрос: нашел ли я ошибку в управлении памятью PHP? Или, может быть, в Zend Framework? Опять таки; увеличив лимит памяти на скрипт в php.ini, я не вижу этой проблемы. Это или удалить второй экземпляр выполнения этого расчета, который использует много памяти.
Я очень, очень уверен, что именно так это и происходит, несмотря на странность того, как это происходит (я никогда не видел такого возврата к началу вызывающей функции). Обычно в этом случае случается, что PHP выдает ошибку и умирает, а не перезапускает вызывающую функцию.