php安全配置記錄和常見錯誤梳理

散盡浮華發表於2016-07-19

 

通常部署完php環境後會進行一些安全設定,除了熟悉各種php漏洞外,還可以通過配置php.ini來加固PHP的執行環境,PHP官方也曾經多次修改php.ini的預設設定。
下面對php.ini中一些安全相關引數的配置進行說明

register_globals
當register_globals = ON時,PHP不知道變數從何而來,也容易出現一些變數覆蓋的問題。因此從最佳實踐的角度,強烈建議設定 register_globals = OFF,這也是PHP新版本中的預設設定。

open_basediropen_basedir
可以限制PHP只能操作指定目錄下的檔案。這在對抗檔案包含、目錄遍歷等攻擊時非常有用,應該為此選項設定一個值。
需要注意的是,如果設定的值是一個指定的目錄,則需要在目錄最後加上一個“/”,否則會被認為是目錄的字首。
open_basedir = /home/web/html/

allow_url_include = Off
為了對抗遠端檔案包含,請關閉此選項,一般應用也用不到此選項。同時推薦關閉的還有allow_url_fopen。

display_errors = Off
錯誤回顯,一般常用於開發模式,但是很多應用在正式環境中也忘記了關閉此選項。錯誤回顯可以暴露出非常多的敏感資訊,為攻擊者下一步攻擊提供便利。推薦關閉此選項。

log_errors = On
在正式環境下用這個就行了,把錯誤資訊記錄在日誌裡。正好可以關閉錯誤回顯。

magic_quotes_gpc = Off
推薦關閉,它並不值得依賴(請參考“注入攻擊”一章),已知已經有若干種方法可以繞過它,甚至由於它的存在反而衍生出一些新的安全問題。XSS、SQL隱碼攻擊等漏洞,都應該由應用在正確的地方解決。同時關閉它還能提高效能。

cgi.fix_pathinfo = 0
若PHP以CGI的方式安裝,則需要關閉此項,以避免出現檔案解析問題(請參考“檔案上傳漏洞”一章)。

session.cookie_httponly = 1  開啟HttpOnly

session.cookie_secure = 1
若是全站HTTPS則請開啟此項。

sql.safe_mode = Off
PHP的安全模式是否應該開啟的爭議一直比較大。一方面,它會影響很多函式;另一方面,它又不停地被黑客們繞過,因此很難取捨。如果是共享環境(比如App Engine),則建議開啟safe_mode,可以和disable_functions配合使用;
如果是單獨的應用環境,則可以考慮關閉它,更多地依賴於disable_functions控制執行環境安全。

disable_functions =
能夠在PHP中禁用函式(如上預設=號後面什麼都不配置)。這是把雙刃劍,禁用函式可能會為開發帶來不便,但禁用的函式太少又可能增加開發寫出不安全程式碼的機率,同時為黑客獲取webshell提供便利。
一般來說,如果是獨立的應用環境,則推薦禁用以下函式:
disable_functions = escapeshellarg, escapeshellcmd, exec,passthru, proc_close, proc_get_status, proc_open, proc_nice,proc_terminate, shell_exec, system, ini_restore, popen, dl,disk_free_space, diskfreespace, set_time_limit, tmpfile, fopen,readfile, fpassthru, fsockopen, mail, ini_alter, highlight_file,openlog, show_source, symlink, apache_child_terminate,apache_get_modules, apache_get_version, apache_getenv,apache_note, apache_setenv, parse_ini_file

php 上傳大檔案主要涉及配置upload_max_filesize和post_max_size兩個選項

曾經遇到的問題:
在網站後臺上傳圖片的時候出現一個非常怪的問題,有時候表單提交可以獲取到值,有時候就獲取不到了,連普通的欄位都獲取不到了,苦思冥想還沒解決,最後問了師傅,
師傅看了說挺奇怪的,然後問我 upload_max_filesize的值改了嗎,我說改了啊,師傅也解決不了了。過了一會師傅問 post_max_size改了嗎,我說那個和上傳沒關係吧,
師傅沒理我,我還是照著自己的想法繼續測試,弄了半天還是不行,最後試了師傅提的意見,成功了,原來上傳是和 post_max_size有關係的。
 
問題總結 :
php.ini配置檔案中的預設檔案上傳大小為 2M,預設upload_max_filesize = 2M ,即檔案上傳的大小為 2M,如果你想上傳超過8M的檔案,比如 20M,
 
必須設定 upload_max_filesize = 20M。但是光設定upload_max_filesize = 20M還是無法實現大檔案的上傳功能,你必須修改 php.ini配置檔案中的post_max_size選項,
其代表允許 POST的資料最大位元組長度,預設為 8M。如果POST 資料超出限制,那麼 $_POST和$_FILES 將會為空。要上傳大檔案,
你必須設定該選項值大於 upload_max_filesize指令的值,我一般設定upload_max_filesize和 post_max_size值相等。
另外如果啟用了記憶體限制,那麼該值應當小於 memory_limit選項的值。
 
檔案上傳的其他注意事項 :
在上傳大檔案時,你會有上傳速度慢的感覺,當超過一定的時間,會報指令碼執行超過 30秒的錯誤,這是因為在php.ini配置檔案中 max_execution_time 配置選項在作怪,
其表示每個指令碼最大允許執行時間 (秒) ,0 表示沒有限制。你可以適當調整 max_execution_time的值,不推薦設定為0。
********************************************************************************************************
解釋:
具體可檢視 PHP手冊 中的 〔php.ini 核心配置選項說明〕
upload_max_filesize 所上傳的檔案的最大大小。 
post_max_size       設定 POST 資料所允許的最大大小。
memory_limit        設定了一個指令碼所能夠申請到的最大記憶體位元組數。

一般來說:memory_limit > post_max_size > upload_max_filesize
 
upload_max_filesize是限制本次上傳的最大值
post_max_size是post資料的最大值, 通過POST提交資料的最大值
一般我們在php中用的是POST方式上傳

=================================================================================
php.ini中記錄PHP錯誤日誌的引數:display_errors與log_errors的區別

1)display_errors 
錯誤回顯,一般常用語開發模式,但是很多應用在正式環境中也忘記了關閉此選項。錯誤回顯可以暴露出非常多的敏感資訊,為攻擊者下一步攻擊提供便利。推薦關閉此選項。 

display_errors = On 
開啟狀態下,若出現錯誤,則報錯,出現錯誤提示。即顯示所有錯誤資訊。 

dispaly_errors = Off 
關閉狀態下,若出現錯誤,則提示:伺服器錯誤,但是不會出現錯誤提示。即關閉所有錯誤資訊

2)log_errors 
在正式環境下用這個就行了,把錯誤資訊記錄在日誌裡。正好可以關閉錯誤回顯。 

log_errors = On    //注意,log_errors設定為On後,那麼dispaly_errors就要設定為Off,這兩個不能同時開啟。

error_log = /Data/logs/php/error.log   //注意,log_errors設定為On時,必須要設定error_log的日誌檔案路徑,並且這個日誌檔案要能有許可權正常寫入。

也就是說log_errors = On時,必須指定error_log檔案,如果沒指定或者指定的檔案沒有許可權寫入,那麼照樣會輸出到正常的輸出渠道,那麼也就使得display_errors 這個指定的Off失效,錯誤資訊還是列印了出來。

對於PHP開發人員來說,一旦專案上線後,第一件事就是應該將display_errors選項關閉,以免因為這些錯誤所透露的路徑、資料庫連線、資料表等資訊而遭到黑客攻擊。 

---------------------------------------------------
一般說來:

測試環境下的php.ini中的錯誤日誌設定:              
error_reporting = E_ALL  
display_errors = On  
html_errors = On  
log_errors = Off  

正式環境下的php.ini中的錯誤日誌設定: 
error_reporting = E_ALL &~ E_NOTICE &~ E_WARNING       //注意這個設定,記得有一次因為這個設定有誤,導致了線上一個業務訪問出現了nginx 500報錯!這個導致了php框架報錯!  
display_errors = Off  
log_errors = On  
html_errors = Off  
error_log = /Data/logs/php/error.log 
ignore_repeated_errors = On  
ignore_repeated_source = On  

簡單講解下各個配置的意義:
error_reporting :設定報告哪些錯誤  
display_errors :設定錯誤是否作為輸出的一部分顯示  
html_errors :設定錯誤資訊是否採用html格式  
log_errors :設定是否記錄錯誤資訊  
error_log :設定錯誤資訊記錄的檔案  
ignore_repeated_errors :是否在同一行中重複顯示一樣的錯誤資訊  
ignore_repeated_source : 是否重複顯示來自同個檔案同行程式碼的錯誤 

==============================================================================
順便記錄下php的頁面老是報時區錯誤的處理過程:

Warning: phpinfo(): It is not safe to rely on the system's timezone settings. You are
*required* to use the date.timezone setting or the date_default_timezone_set()
function. In case you used any of those methods and you are still getting this
warning, you most likely misspelled the timezone identifier. We selected the
timezone 'UTC' for now, but please set date.timezone to select your timezone. in
/usr/local/www/zabbix2/phpinfo.php on line 2
date/time support enabled
"Olson" Timezone Database Version 2013.8
Timezone Database internal
Default timezone UTC

修改php.ini 檔案
# vim /usr/local/php/etc/php.ini
........
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = Asia/Shanghai

注意必須把要 php.ini 複製一份到/usr/local/php/lib/下,否則 php 服務預設會到這個 lib 目錄下讀取 php.ini 檔案,沒有的話,就是預設時區UTC,這個時區和北京時間相差8小時。
[root@i-gxcmjlge lib]# pwd
/usr/local/php/lib
[root@i-gxcmjlge lib]# ll
total 72
drwxr-xr-x 14 root root 4096 Nov 18 01:11 php
-rw-r--r-- 1 root root 65681 Nov 18 15:01 php.ini

然後重啟php服務和nginx/apache服務

除了php.ini檔案,還要注意php-fpm.conf配置,如下:

[root@i-v5lmgh7y etc]# cat php-fpm.conf|grep -v "^;"|grep -v "^$"
[global]
pid = run/php-fpm.pid   //pid 設定,預設在安裝目錄中的 var/run/php-fpm.pid,建議開啟
error_log = log/php-fpm.log   //錯誤日誌,預設在安裝目錄中的 var/log/php-fpm.log
log_level = notice      //錯誤級別. 可用級別為: alert(必須立即處理), error(錯誤情況), warning(警告情況), notice(一般重要資訊), debug(除錯資訊). 預設: notice.
emergency_restart_threshold = 60
emergency_restart_interval = 60s //表示在emergency_restart_interval所設值內出現SIGSEGV或者SIGBUS錯誤的php-cgi程式數如果超過 emergency_restart_threshold個,php-fpm就會優雅重啟。這兩個選項一般保持預設值。
process_control_timeout = 0  //設定子程式接受主程式複用訊號的超時時間. 可用單位: s(秒), m(分), h(小時), 或者 d(天) 預設單位: s(秒). 預設值: 0.
daemonize = yes   //後臺執行fpm,預設值為yes,如果為了除錯可以改為no。在FPM中,可以使用不同的設定來執行多個程式池。 這些設定可以針對每個程式池單獨設定。

[www]
user = nobody     //啟動程式的帳戶
group = nobody    //啟動程式的組
listen = 127.0.0.1:9000    //fpm監聽埠,即nginx中php處理的地址,一般預設值即可。可用格式為: 'ip:port', 'port', '/path/to/unix/socket'. 每個程式池都需要設定.
listen.backlog = 1024   //backlog數,,由作業系統決定,-1表示無限制。也可以註釋掉此行。
listen.allowed_clients = 127.0.0.1  //(可以不設定此行)允許訪問FastCGI程式的IP,如果沒有設定或者為空,則允許任何伺服器請求連線。設定any為不限制IP,如果要設定其他主機的nginx也能訪問這臺FPM程式,listen處要設定成本地可被訪問的IP。預設值是any。每個地址是用逗號分隔. 

pm = static   //對於專用伺服器,pm可以設定為static,如何控制子程式,選項有static和dynamic。如果選擇static,則由pm.max_children指定固定的子程式數。如果選擇dynamic,則由下開引數決定:
pm.max_children = 512   //子程式最大數
pm.start_servers = 387  //啟動時的程式數
pm.min_spare_servers = 32  //保證空閒程式數最小值,如果空閒程式小於此值,則建立新的子程式
pm.max_spare_servers = 387  //保證空閒程式數最大值,如果空閒程式大於此值,此進行清理
pm.max_requests = 1024  //設定每個子程式重生之前服務的請求數. 對於可能存在記憶體洩漏的第三方模組來說是非常有用的. 如果設定為 '0' 則一直接受請求. 等同於 PHP_FCGI_MAX_REQUESTS 環境變數. 預設值: 0
pm.status_path = /status   //fpm狀態頁面的網址. 如果沒有設定, 則無法訪問狀態頁面. 預設值: none. munin監控會使用到

ping.path = /ping   //fpm監控頁面的ping網址. 如果沒有設定, 則無法訪問ping頁面. 該頁面用於外部檢測FPM是否存活並且可以響應請求. 請注意必須以斜線開頭 (/)。可以不設定此行。
ping.response = pong  //用於定義ping請求的返回相應. 返回為HTTP 200的text/plain 格式文字. 預設值: pong。可以不設定此行。
 
slowlog = var/log/slow.log   //慢請求的記錄日誌,配合request_slowlog_timeout使用
request_slowlog_timeout = 0  //設定單個請求的超時中止時間. 該選項可能會對php.ini設定中的'max_execution_time'因為某些特殊原因沒有中止執行的指令碼有用. 設定為 '0' 表示 'Off'.當經常出現502錯誤時可以嘗試更改此選項。
request_terminate_timeout = 10s  //當一個請求該設定的超時時間後,就會將對應的PHP呼叫堆疊資訊完整寫入到慢日誌中. 設定為 '0' 表示 'Off'。可以不設定此行。
rlimit_files = 65535    //設定檔案開啟描述符的rlimit限制. 預設值: 系統定義值預設可開啟控制程式碼是1024,可使用 ulimit -n檢視,ulimit -n 2048修改。
rlimit_core = 0   //設定核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整數. 預設值: 系統定義值.
catch_workers_output = yes  //重定向執行過程中的stdout和stderr到主要的錯誤日誌檔案中. 如果沒有設定, stdout 和 stderr 將會根據FastCGI的規則被重定向到 /dev/null . 預設值: 空.

=================Nginx+Php中限制站點目錄防止跨站的配置方案記錄(使用open_basedir)===============
方法1)在Nginx配置檔案中加入:

fastcgi_param  PHP_VALUE  "open_basedir=$document_root:/tmp/:/proc/";

通常nginx的站點配置檔案裡用了include fastcgi.conf;,這樣的,把這行加在fastcgi.conf裡就OK了。
如果某個站點需要單獨設定額外的目錄,把上面的程式碼寫在include fastcgi.conf;這行下面就OK了,會把fastcgi.conf中的設定覆蓋掉。
這種方式的設定需要重啟nginx後生效。

方法2)在php.ini中加入

[HOST=www.wangshibo.com]
open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/
[PATH=/home/www/www.wangshibo.com]
open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/

這種方式的設定需要重啟php-fpm後生效。

方法3)在網站根目錄下建立.user.ini檔案,並在該檔案中寫入下面資訊:

open_basedir=/home/www/www.wangshibo.com:/tmp/:/proc/

這種方式不需要重啟nginx或php-fpm服務。安全起見應當取消掉.user.ini檔案的寫許可權。

php.ini中建議禁止的函式如下:

disable_functions = pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig, pcntl_signal, pcntl_signal_dispatch, pcntl_get_last_error, pcntl_strerror, pcntl_sigprocmask, pcntl_sigwaitinfo, pcntl_sigtimedwait, pcntl_exec, pcntl_getpriority, pcntl_setpriority, eval, popen, passthru, exec, system, shell_exec, proc_open, proc_get_status, chroot, chgrp, chown, ini_alter, ini_restore, dl, pfsockopen, openlog, syslog, readlink, symlink, popepassthru, stream_socket_server, fsocket, chdir

====================php啟動後,9000埠沒有起來?=====================
問題描述:
php服務安裝後,啟動php-fpm,啟動的時候沒有報錯。然後ps -ef|grep php沒有發現程式起來,lsof -i:9000發現埠也沒有起來。
檢視日誌,發現系統所允許開啟的檔案數超過了預定設定。

[root@i-v5lmgh7y etc]# /usr/local/php/sbin/php-fpm
[root@i-v5lmgh7y etc]# ps -ef|grep php
[root@i-v5lmgh7y etc]#lsof -i:9000
[root@i-v5lmgh7y etc]#

檢視錯誤日誌發現問題:
[root@i-v5lmgh7y log]# tail -f php-fpm.log
[15-Nov-2015 23:53:15] NOTICE: fpm is running, pid 18277
[15-Nov-2015 23:53:15] ERROR: failed to prepare the stderr pipe: Too many open files (24)
[15-Nov-2015 23:53:16] NOTICE: exiting, bye-bye!
[15-Nov-2015 23:53:59] NOTICE: fpm is running, pid 18855
[15-Nov-2015 23:53:59] ERROR: failed to prepare the stderr pipe: Too many open files (24)
[15-Nov-2015 23:54:00] NOTICE: exiting, bye-bye!

發現是系統允許開啟的檔案數超了預定的設定。需要調大這個值:
[root@i-v5lmgh7y etc]# ulimit -n
1024
[root@i-v5lmgh7y etc]# ulimit -n 65535    //臨時解決辦法
[root@i-v5lmgh7y etc]# ulimit -n
65535


永久解決辦法:
在/etc/security/limits.conf檔案底部新增下面四行內容:
[root@i-v5lmgh7y etc]# cat /etc/security/limits.conf
.........
# End of file
* soft nproc unlimited
* hard nproc unlimited
* soft nofile 65535
* hard nofile 65535

然後再次啟動php-fpm程式,9000埠就能正常啟動了
[root@i-v5lmgh7y etc]# /usr/local/php/sbin/php-fpm
[root@i-v5lmgh7y etc]# ps -ef|grep php
root 21055 1 0 00:12 ? 00:00:00 php-fpm: master process
(/usr/local/php/etc/php-fpm.conf)
nobody 21056 21055 0 00:12 ? 00:00:00 php-fpm: pool www
nobody 21057 21055 0 00:12 ? 00:00:00 php-fpm: pool www

===============下面梳理幾個常見的php不恰當配置引發的問題=================

1)request_terminate_timeout的值如果設定為0或者過長的時間,可能會引起file_get_contents的資源問題。
如果訪問請求的遠端資源反應過慢,php-cgi程式就會一直卡在那裡不會超時。雖然php.ini檔案裡面max_execution_time可以設定PHP指令碼的最大執行時間,但是,在php-cgi(php-fpm) 中該引數不會起效。真正能夠控制PHP指令碼最大執行時間的是php-fpm.conf配置檔案中的request_terminate_timeout引數。

request_terminate_timeout預設值為0秒,也就是說,PHP指令碼會一直執行下去。這樣當所有的php-cgi程式都卡住時,這臺Nginx+PHP的WebServer已經無法再處理新的PHP請求了,Nginx 將給使用者返回“502 Bad Gateway”。
修改該引數,設定一個PHP指令碼最大執行時間是必要的,但是治標不治本。例如改成30s,如果發生訪問獲取網頁內容較慢的情況,這就意味著150個php-cgi程式,每秒鐘只能處理5個請求,WebServer同樣很難避免”502 Bad Gateway”。

解決辦法是request_terminate_timeout設定為10s或者一個合理的值。

2)max_requests引數配置不當,可能會引起間歇性502錯誤
設定每個子程式重生之前服務的請求數. 對於可能存在記憶體洩漏的第三方模組來說是非常有用的. 
如果設定為0,則一直接受請求,等同於php_fcgi_max_requests環境變數。預設值為 0.
比如:pm.max_requests = 1000  這個配置的意思是,當一個 php-cgi 程式處理的請求數累積到500個後,自動重啟該程式。

但是為什麼要重啟程式呢?
一般在專案中,多多少少都會用到一些PHP的第三方庫,這些第三方庫經常存在記憶體洩漏問題,如果不定期重啟php-cgi程式,勢必造成記憶體使用量不斷增長。因此php-fpm作為php-cgi的管理器,提供了這麼一項監控功能,對請求達到指定次數的php-cgi程式進行重啟,保證記憶體使用量不增長。正是因為這個機制,在高併發的站點中,經常導致502錯誤,
目前解決方法是,把這個值儘量設定大些,儘可能減少php-cgi重新SPAWN的次數,同時也能提高總體效能。在實際的生產環境中發現,記憶體洩漏如果不明顯,可以將這個值設定得非常大(比如204800)。要根據自己的實際情況設定這個值(比如我們線上設定1024),不能盲目地加大。
話說回來,這套機制目的只為保證php-cgi不過分地佔用記憶體,為何不通過檢測記憶體的方式來處理呢?通過設定程式的峰值內在佔用量來重啟php-cgi程式,會是更好的一個解決方案。

3)php-fpm的慢日誌,debug及異常排查神器
request_slowlog_timeout設定一個超時的引數,slowlog設定慢日誌的存放位置

==========php報錯日誌:PHP Deprecated:Automatically populating $HTTP_RAW_POST_DATA is deprecated=========

之前將線上php服務升級到5.6.x版本後,php-error.log報出錯誤:
PHP Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated
原因:
上面的報錯意思是“自動變數$HTTP_RAW_POST_DATA已過時(deprecated)”
這個問題和PHP版本有關係,PHP5.6之後的高版本都已廢棄了$HTTP_RAW_POST_DATA這個全域性變數設定,可以使用 php://input 替代 $HTTP_RAW_POST_DATA。
使用always_populate_raw_post_data會導致在填充$HTTP_RAW_POST_DATA時產生E_DEPRECATED 錯誤。 
設定always_populate_raw_post_data 為-1來體驗新的行為,因為這樣會強制 $HTTP_RAW_POST_DATA 未定義,所以也不會導致 E_DEPRECATED的錯誤) 來體驗新的行為。

解決方法: 
修改php.ini配置檔案:
[root@dev-new-test etc]# vim php.ini
........
; Always populate the $HTTP_RAW_POST_DATA variable.
;always_populate_raw_post_data = On
always_populate_raw_post_data = -1
.......

然後重啟php服務即可!

===================phpinfo.php資訊洩露漏洞===================

修復:
若無需要可以將一些php的危險函式禁用,開啟/etc/php.ini檔案,查詢到 disable_functions,新增需禁用的以下函式名:
[root@localhost ~]# vim /usr/local/php/etc/php.ini
disable_functions = phpinfo,eval,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,fsockopen

expose_php = Off        //隱藏版本號等資訊

===============php檔案修改後,訪問這個檔案不會立即更新內容,而是過一會兒才回更新=============

原因是php啟動了opcache的模組(php的程式碼優化和加速模組)!執行php-config命令可以看到php編譯安裝時跟了--enable-opcache參賽,直接訪問如下的php的測試檔案:
# cat test.php
<?php
phpinfo()
?>

可以看到介面中的“Zend OPcache”模組顯示下面兩行,表示opcache被啟用了!
Opcode Caching  Up and Running
Optimization    Enabled

[root@iZwz96p8207vmn7amyxvw6Z ~]# cat /usr/local/php/etc/php.ini|grep opcache
[opcache]
;opcache.enable=0
;opcache.enable_cli=0
;opcache.memory_consumption=64
;opcache.interned_strings_buffer=4
;opcache.max_accelerated_files=2000
;opcache.max_wasted_percentage=5
;opcache.use_cwd=1
;opcache.validate_timestamps=1
;opcache.revalidate_freq=2
;opcache.revalidate_path=0
;opcache.save_comments=1
;opcache.load_comments=1
;opcache.fast_shutdown=0
;opcache.enable_file_override=0
;opcache.optimization_level=0xffffffff
;opcache.inherited_hack=1
;opcache.dups_fix=0
;opcache.blacklist_filename=
;opcache.max_file_size=0
;opcache.consistency_checks=0
;opcache.force_restart_timeout=180
;opcache.error_log=
;opcache.log_verbosity_level=1
;opcache.preferred_memory_model=
;opcache.protect_memory=0
; opcache.validate_permission=0
; opcache.validate_root=0

[root@iZwz96p8207vmn7amyxvw6Z ~]# /usr/local/php/bin/php -m
........

[Zend Modules]
Zend OPcache
the ionCube PHP Loader (enabled) + Intrusion Protection from ioncube24.com (unconfigured)

這就導致了php檔案修改後,在瀏覽器裡訪問不會立馬生效,需要過30秒左右才生效!因為有opcache快取的原因!

解決辦法:
在php檔案內容的前面新增清理opcache的函式,即opcache_reset();  如下:
[root@iZwz96p8207vmn7amyxvw6Z itime]# cat test.php 
<?php
   opcache_reset();                      //這一行就是清理opcache快取
   echo  'hjhjhjhjhjh';
?>

這樣訪問test.php檔案,當它的內容更新時,在新的瀏覽器頁面裡開啟就是更新後的內容了。
如果在老頁面裡繼續訪問,第一次刷時清理快取,第二次重新整理就是更新後的內容了!

相關文章