В PHP, как мне определить, какой * фактический * скрипт вызвал фатальную ошибку (превышен размер памяти)?

#php #debugging #error-handling #fatal-error

#php #отладка #обработка ошибок #фатальная ошибка

Вопрос:

Я продолжаю получать таинственную ошибку, подобную этой, зарегистрированной:

 PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 134217736 bytes) in C:BLABLABLAunrelated.php on line 24
 

Конечно, unrelated.php это не тот скрипт, который выполняет фактический вызов функции. Это всего лишь один из многих файлов с функциями-оболочками в моей платформе.

Мой расширенный регистратор ошибок PHP, который использует debug_backtrace() для того, чтобы иметь возможность перебирать и регистрировать «полную цепочку» вызовов функций, приводящих к ошибке. Однако даже этот мой «умный» регистратор в этом случае терпит неудачу:

 Allowed memory size of 1,07 GB exhausted (tried to allocate 134,22 MB):

    Row 310 @ "C:BLABLAdebug.php"
    Row 1844 @ "C:BLABLAirrelephpant.php"
 

Ни один из этих файлов не является исходным скриптом, который фактически выполняется, что приводит к этой ошибке.

Все файлы, упомянутые выше, никогда не запускаются напрямую. Они являются лишь частью моей структуры, перенося функции из PHP или друг из друга.

Я этого не понимаю. debug_backtrace() Кажется, что все указывает на то, что он найдет «самый внешний» / базовый скрипт, но в данном случае это явно не так. Я предполагаю, что это из-за ФАТАЛЬНОЙ ошибки …? Что я могу сделать, чтобы он действительно регистрировал фактический скрипт, который был запущен в CLI и в конечном итоге вызвал эту ошибку? (Чтобы я мог назначить больше оперативной памяти специально для этого.)

Ответ №1:

Вы можете использовать профилировщик Xdebug, чтобы увидеть, где выделено максимальное количество памяти. Вы можете увеличить объем памяти, добавив эту строку в свой unrelated.php скрипт сверху ini_set('memory_limit', '512M'); или любое другое увеличение объема памяти, которое вам нужно.

Комментарии:

1. 1. XDebug всегда был для меня загадкой, поэтому я бы предпочел не изучать / устанавливать / разбираться с этим, если это возможно. 2. Да, я знаю, что могу добавить это к другим файлам, но я не хочу, чтобы они могли использовать неограниченное / много оперативной памяти — только конкретный скрипт, который действительно в этом нуждается.

2. @user17535142 «конкретного скрипта» нет, есть только ваше приложение. Тот факт, что он состоит из более чем одного файла исходного кода, не имеет значения, особенно с точки зрения управления ресурсами. Профилирование вашего приложения — правильный ответ.

3. @Sammitch Да? Я запускаю php test.php . test.php вызывает вызов функции other.php . other.php это единственный, который отображается в журнале ошибок. Как мне получить test.php ? Действительно утомительно все время повторяться и заставлять людей притворяться, что они не понимают, что я имею в виду.

4. Подумайте о include('other.php') инструкции как о простом копировании / вставке содержимого other.php вместо инструкции include test.php . То, что исходный код находится внутри другого файла, не означает, что этот файл каким-то образом имеет свой собственный контекст выполнения или распределение ресурсов. Разбиение кода PHP на несколько помогает организовать код так, чтобы людям было легко управлять и организовывать. Вы можете включить 100 файлов, но для PHP это все равно всего одно приложение. Опять же, если вы хотите знать, где накапливается память, вам нужно использовать профилировщик.