Điều khó hiểu ở đây là cài đặt trông giống như một số nguyên với một số cú pháp đặc biệt, nhưng được định nghĩa bên trong dưới dạng một chuỗi. Chuỗi sau đó được phân tích thành một biến toàn cục riêng biệt bất cứ khi nào giá trị được thay đổi. Điều quan trọng, kết quả của việc phân tích chuỗi thành một số nguyên không được lưu lại vào bảng cài đặt, vì vậy khi bạn gọi phpinfo()
, bạn sẽ thấy đầu vào ban đầu, không phải giá trị được phân tích cú pháp.
Bạn có thể thấy điều này trong nguồn:
Cú pháp được hỗ trợ cuối cùng được định nghĩa trong zend_atol
đó:
- phân tích chuỗi cho một giá trị số, bỏ qua bất kỳ văn bản bổ sung nào
- vẻ ở ký tự cuối cùng của chuỗi, và nhân lên giá trị trước nếu nó là
g
, G
, m
, M
, k
, hoặcK
Một giá trị không có chữ số khi bắt đầu sẽ được phân tích thành 0. Khi đặt biến toàn cục, điều này sẽ đặt giới hạn bộ nhớ ở mức tối thiểu cho phép, dựa trên hằng sốZEND_MM_CHUNK_SIZE
.
Bạn có thể thấy hiệu ứng bằng cách đặt giới hạn bộ nhớ, sau đó chạy một vòng lặp phân bổ nhanh một lượng lớn bộ nhớ và xem những gì xuất hiện trong thông báo lỗi. Ví dụ:
# 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