Чи PHP робить який-небудь аналіз на файл php.ini?


24

Запуск PHP версії 7.1.30 під RHEL 7.7.

Я хотів би підмінити пам'ять_ліміт, але не був впевнений, чи маю синтаксис правильно (тобто 256 Мб або 256 Мб). Отже, для початку я поставив неправильне значення "Hugo" в якості налаштування memory_limit. Проблема з цим полягає в тому, що в phpinfo () (запускається під httpd) буквально є рядок "Hugo", тобто:

введіть тут опис зображення

Тож це мене трохи занепокоєло, що PHP насправді не проводить перевірки здоровості щодо цінності. (Якщо надане значення було поганим, я б очікував, що воно повернеться до дефолту, наприклад)

Хтось може прокоментувати це - зокрема, як ви знаєте, чи буде PHP застосовувати речі (якщо може бути надана довільна рядок).


4
Відмінне запитання.
тинк

3
Звідси: php.net/manual/en/faq.using.php#faq.using.shorthandbytes я вважаю, що це те саме, що (int) 'HUGO'; // => 0. Що починає виходити з ладу на моїй машині при 2 Мб пам'яті, що використовується.
Йоші


@Yoshi Я думаю, ви повинні опублікувати свою відповідь. Це хороше пояснення
Максим Федоров

@MaksymFedorov Я вагаюся, оскільки у мене немає реального посилання на моє припущення. Наразі це лише спостереження.
Йоші

Відповіді:


19

Тут заплутаною є те, що параметр виглядає як ціле число з якимось спеціальним синтаксисом, але внутрішньо визначається як рядок. Потім рядок аналізується на окрему глобальну змінну щоразу, коли значення змінюється. Принципово важливо, що результат розбору рядка на ціле число не зберігається назад у таблиці налаштувань, тому під час дзвінка phpinfo()ви бачите оригінальний вхід, а не розбір значення.

Ви можете побачити це у джерелі:

Підтримуваний синтаксис визначається в кінцевому підсумку, у zend_atolякому:

  1. аналізує рядок на числове значення, ігноруючи будь-який додатковий текст
  2. дивиться на останній символ рядка, і примножує попереднє значення , якщо воно g, G, m, M, k, абоK

Значення без цифр на початку буде розбиратися на нуль. При встановленні глобальної змінної це встановить ліміт пам'яті на мінімально дозволеному, виходячи з постійної ZEND_MM_CHUNK_SIZE.

Ефект можна побачити, встановивши ліміт пам’яті, потім запустивши цикл, який швидко виділяє великий об’єм пам’яті та бачить, що з’являється у повідомленні про помилку. Наприклад:

# Invalid string; sets to compiled minimum
php -r 'ini_set("memory_limit", "HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 2097152 bytes exhausted

# Number followed by a string; takes the number
php -r 'ini_set("memory_limit", "4000000 HUGO"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4000000 bytes exhausted

# Number followed by a string, but ending in one of the recognised suffixes
# This finds both the number and the suffix, so is equivalent to "4M", i.e. 4MiB
php -r 'ini_set("memory_limit", "4 HUGO M"); while(true) $a[]=$a;'
# -> PHP Fatal error:  Allowed memory size of 4194304 bytes exhausted

Дякую @IMSoP за велику оцінку. Чи варто повідомляти про подібні речі у будь-якому виправі? Я знаходжу відповідь, що phpinfo () породжує дуже контр-інтуїтивно зрозумілий характер. І деякий вихід налагодження для того, що робить php, коли він стикається з несподіваними значеннями, теж не зминеться.
тинк

1
@tink Я думаю, ви можете надіслати запит на функцію на bugs.php.net або надіслати повідомлення до списку розсилки Internals, де саме відбувається найбільше узгодження. Я знайшов подібний запит кілька років тому , але, схоже, не було відповіді.
IMSoP

Дякую ще раз, розглянемо це! :)
тирк

0

По-перше, спочатку нам потрібно зрозуміти, як PHP.ini працює в процесі інтерпретації робочого процесу. memory_limit - це директиви для PHP.

при використанні функції PHP вам потрібно зробити щось подібне ini_set(‘memory_limit’,’256MB’). Отже, ця функція тимчасово встановить ваше значення змінної інтерпретатора. Якщо ви бачите ближче, ви можете отримати два стовпці: Один призначений для локального, а один - для глобального. Це показує здатність значень до індивіда відповідно.

Але, коли ви визначили глобальний, вам потрібно встановити суфікс з K, M, G відповідно. Якщо ми перевищимо це значення за допомогою apache .htaccess, воно вимагає того ж для PHP fpm.


3
Я хотів би відзначити, що ОП не запитує, як встановити межу пам’яті :)
Karolis
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.