PHP có thực hiện bất kỳ phân tích cú pháp nào trên tệp php.ini không?


24

Chạy phiên bản PHP 7.1.30 trong RHEL 7.7.

Tôi muốn tăng bộ nhớ_limit, nhưng không chắc là tôi có đúng cú pháp hay không (tức là 256M hoặc 256MB). Vì vậy, để bắt đầu, tôi đặt một giá trị xấu "Hugo" vào cài đặt memory_limit. Vấn đề với điều này là kết quả của phpinfo () (chạy dưới httpd) theo nghĩa đen có chuỗi "Hugo", nghĩa là:

nhập mô tả hình ảnh ở đây

Vì vậy, điều này khiến tôi hơi lo ngại rằng PHP thực sự không thực hiện bất kỳ việc kiểm tra giá trị nào cho (các) giá trị. (Nếu giá trị được cung cấp là xấu, tôi sẽ mong nó trở lại mặc định, vd)

Bất cứ ai cũng có thể nhận xét về điều này - đặc biệt, làm thế nào để bạn biết liệu PHP sẽ thực thi mọi thứ hay không (nếu một chuỗi tùy ý có thể được cung cấp).


4
Câu hỏi tuyệt vời.
tink

3
Từ đây: php.net/manual/en/faq.USE.php#faq.USE.shorthandbytes Tôi cho rằng nó giống như (int) 'HUGO'; // => 0. Mà bắt đầu thất bại trên máy của tôi ở mức 2 MB bộ nhớ được sử dụng.
Yoshi


@Yoshi Tôi nghĩ bạn nên công khai câu trả lời của mình. Đó là một lời giải thích tốt
Maksym Fedorov

@MaksymFedorov Tôi do dự vì tôi không có tài liệu tham khảo thực sự cho giả định của mình. Bây giờ nó chỉ là một quan sát.
Yoshi

Câu trả lời:


19

Đ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 đó:

  1. 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
  2. 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

Cảm ơn bạn @IMSoP vì đánh giá tuyệt vời đó. Có nên báo cáo loại điều này trong bất kỳ loại bugtracker nào không? Tôi thấy phản hồi mà phpinfo () tạo ra rất phản trực quan. Và một số đầu ra gỡ lỗi cho những gì php làm khi gặp các giá trị không mong muốn cũng sẽ không ổn.
tink

1
@tink Tôi đoán bạn có thể đưa ra một yêu cầu tính năng trên bug.php.net hoặc gửi tin nhắn đến danh sách gửi thư của Internals , nơi xảy ra hầu hết sự phối hợp. Tôi đã tìm thấy một yêu cầu tương tự từ vài năm trước , nhưng dường như không có phản hồi nào.
IMSoP

Cảm ơn một lần nữa, sẽ xem xét điều đó! :)
tink

0

Trước tiên, trước tiên chúng ta cần hiểu cách thức hoạt động của PHP.ini theo cách diễn giải quy trình. memory_limit là chỉ thị cho PHP.

Khi sử dụng với chức năng PHP, bạn phải làm một cái gì đó như thế này ini_set(‘memory_limit’,’256MB’) . Vì vậy, hàm này sẽ tạm thời đặt giá trị của bạn cho biến trình thông dịch. Nếu bạn nhìn gần hơn thì bạn có thể lấy hai cột Một dành cho Địa phương và Một dành cho toàn cầu. Điều đó cho thấy khả năng của các giá trị tương ứng với từng cá nhân.

Nhưng, khi bạn xác định toàn cầu, bạn cần đặt hậu tố với K, M, G tương ứng. Nếu chúng ta vượt quá giá trị này bằng cách sử dụng apache .htaccess, nó yêu cầu tương tự cho fpm PHP.


3
Tôi muốn vui lòng chỉ ra rằng OP không hỏi cách đặt giới hạn bộ nhớ :)
Karolis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.