สิ่งที่สับสนที่นี่คือการตั้งค่าดูเหมือนว่าจำนวนเต็มกับไวยากรณ์พิเศษบางอย่าง แต่ถูกกำหนดภายในเป็นสตริง จากนั้นสตริงจะถูกวิเคราะห์แยกเป็นตัวแปรโกลบอลที่แยกจากกันเมื่อใดก็ตามที่มีการเปลี่ยนแปลงค่า สำคัญผลลัพธ์ของการแยกสตริงเป็นจำนวนเต็มจะไม่ถูกบันทึกกลับไปที่ตารางการตั้งค่าดังนั้นเมื่อคุณโทร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