Тут заплутаною є те, що параметр виглядає як ціле число з якимось спеціальним синтаксисом, але внутрішньо визначається як рядок. Потім рядок аналізується на окрему глобальну змінну щоразу, коли значення змінюється. Принципово важливо, що результат розбору рядка на ціле число не зберігається назад у таблиці налаштувань, тому під час дзвінка phpinfo()
ви бачите оригінальний вхід, а не розбір значення.
Ви можете побачити це у джерелі:
Підтримуваний синтаксис визначається в кінцевому підсумку, у zend_atol
якому:
- аналізує рядок на числове значення, ігноруючи будь-який додатковий текст
- дивиться на останній символ рядка, і примножує попереднє значення , якщо воно
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