昨天試著把系統移植到PHP 7.1上執行看看,系統裝完瀏覽器一開能看到登入畫面,正高興著,結果就發現登入不進去,看起來像是Session方面的問題。
問題原因:
在 system/libraries/Session/Session.php:129
// Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers
if (isset($_COOKIE[$this->_config['cookie_name']])
&& (
! is_string($_COOKIE[$this->_config['cookie_name']])
OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']])
)
)
{
unset($_COOKIE[$this->_config['cookie_name']]);
}
這邊會檢查存在$_COOKIE的session id格式是否正確,剛好我現在的格式不符(你可以透過cookie值或是session_id()查看),所以這個cookie值就被清掉了,導致session值也取不出來。
解決方法1
然後找到官網上的說明(如下),原來session ID的長度現在是可以設定的,然後我修改php.ini把長度變更為40,還是不行。
** session.sid_length **
session.sid_length allows you to specify the length of session ID string. Session ID length can be between 22 to 256. The default is 32. If you need compatibility you may specify 32, 40, etc. Longer session ID is harder to guess. At least 32 chars is recommended.Compatibility Note: Use 32 for session.hash_func=0 (MD5) and session.hash_bits_per_character=4,session.hash_func=1 (SHA1) and session.hash_bits_per_character=6. Use 26 for session.hash_func=0 (MD5) and session.hash_bits_per_character=5. Use 22 for session.hash_func=0 (MD5) andsession.hash_bits_per_character=6. You must configure INI values to have at least 128 bits in session ID. Do not forget set appropriate value to session.sid_bits_per_character, otherwise you will have weaker session ID.
**Note**: This setting is introduced in PHP 7.1.0.
還有一個問題,看到修改後的session id雖然長度對了,但有a-f以外的字元,繼續找...
session.sid_bits_per_character
session.sid_per_character allows you to specify the number of bits in encoded session ID character. The possible values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", ","). The default is 4. The more bits results in stronger session ID. 5 is recommended value for most environments.
**Note**: This setting is introduced in PHP 7.1.0.
再把這個改為4,然後就可以了。
解決方法 2
回頭到Codeigniter的GitHub查,這問題在目前最新的版本(3.1.3)已經修改了,所以你也可以考慮把系統底層升級。