Apakah PHP melakukan parsing pada file php.ini?

24

Menjalankan PHP Versi 7.1.30 di bawah RHEL 7.7.

Saya ingin bertemu memory_limit, tetapi tidak yakin apakah saya memiliki hak sintaksis (yaitu 256M atau 256MB). Jadi untuk memulai dengan saya menempatkan nilai buruk "Hugo" sebagai pengaturan memory_limit. Masalah dengan ini adalah hasil dari phpinfo () (dijalankan di bawah httpd) secara harfiah memiliki string "Hugo", yaitu:

masukkan deskripsi gambar di sini

Jadi ini membuat saya agak khawatir bahwa PHP tidak benar-benar melakukan kewarasan memeriksa nilai (s). (Jika nilai yang diberikan buruk, saya berharap akan kembali ke default, misalnya)

Adakah yang bisa mengomentari ini - khususnya, bagaimana Anda tahu apakah PHP akan menegakkan sesuatu (jika string arbiter dapat disediakan).

Patrick Rynhart
sumber
4
Pertanyaan yang sangat bagus
tink
3
Dari ini: php.net/manual/en/faq.using.php#faq.using.shorthandbytes Saya menganggap itu sama dengan (int) 'HUGO'; // => 0. Yang mulai gagal pada mesin saya pada 2MB memori yang digunakan.
Yoshi
Sebagai catatan, sintaks yang benar adalahmemory_limit 256M .
Tigger
@Yoshi Saya pikir Anda harus mempublikasikan jawaban Anda. Ini penjelasan yang bagus
Maksym Fedorov
@MaksymFedorov Saya ragu karena saya tidak punya referensi nyata untuk asumsi saya. Untuk saat ini hanya sebuah pengamatan.
Yoshi

Jawaban:

19

Yang membingungkan di sini adalah bahwa pengaturannya terlihat seperti integer dengan beberapa sintaks khusus, tetapi secara internal didefinisikan sebagai string. String kemudian diuraikan menjadi variabel global yang terpisah setiap kali nilainya diubah. Yang terpenting, hasil parsing string ke integer tidak disimpan kembali ke tabel pengaturan, jadi ketika Anda menelepon phpinfo(), Anda melihat input asli, bukan nilai parsing.

Anda dapat melihat ini di sumber:

Sintaks yang didukung pada akhirnya ditentukan di zend_atolmana:

  1. mem-parsing string untuk nilai numerik, mengabaikan teks tambahan apa pun
  2. terlihat pada karakter terakhir dari string, dan mengalikan nilai sebelumnya jika g, G, m, M, k, atauK

Nilai tanpa digit di awal akan diuraikan sebagai nol. Saat mengatur variabel global, ini akan mengatur batas memori ke minimum yang diizinkan, berdasarkan konstanta ZEND_MM_CHUNK_SIZE.

Anda dapat melihat efeknya dengan menetapkan batas memori, kemudian menjalankan loop yang dengan cepat mengalokasikan sejumlah besar memori dan melihat apa yang keluar dalam pesan kesalahan. Contohnya:

# 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
sumber
Terima kasih @IMSoP untuk penilaian hebat itu. Haruskah seseorang melaporkan hal semacam ini di bugtracker? Saya menemukan respons yang dihasilkan phpinfo () sangat kontra-intuitif. Dan beberapa hasil debug untuk apa yang dilakukan php ketika menemukan nilai yang tidak diharapkan juga tidak akan salah.
tink
1
@tink Saya kira Anda dapat mengajukan permintaan fitur di bugs.php.net , atau mengirim pesan ke milis Internal yang merupakan tempat koordinasi paling banyak terjadi. Saya menemukan permintaan serupa dari beberapa tahun yang lalu , tetapi sepertinya tidak mendapat tanggapan.
IMSoP
Terima kasih sekali lagi, akan melihatnya! :)
tink
0

Hal pertama yang pertama, Kita pertama-tama harus memahami bagaimana PHP.ini bekerja dengan cara interpretasi alur kerja. memory_limit adalah arahan untuk PHP.

saat menggunakan dengan fungsi PHP Anda harus melakukan sesuatu seperti ini ini_set(‘memory_limit’,’256MB’). Jadi, fungsi ini untuk sementara waktu akan menetapkan nilai Anda ke variabel interpreter. Jika Anda melihat lebih dekat maka Anda bisa mendapatkan dua kolom Satu untuk Lokal dan Satu untuk global. Itu menunjukkan kemampuan nilai untuk masing-masing individu.

Tapi, Ketika Anda didefinisikan untuk global, Anda perlu menetapkan sebagai akhiran dengan K, M, G masing-masing. Jika kita melebihi nilai ini menggunakan apache .htaccess, ia memerlukan hal yang sama untuk PHP fpm.

Pranav Bhatt
sumber
3
Saya ingin menunjukkan bahwa OP tidak menanyakan cara mengatur batas memori :)
Karolis