我目前正在将旧的Ubuntu 10.04服务器迁移到Ubuntu 14.04(PHP 5.5.9,Apache 2.4)。旧服务器使用fcgi,新服务器使用php-fpm。除了一个非常特殊的问题外,一切都按预期工作:
依赖session_set_save_handler
的所有应用都无法正常工作(在我的情况下,这适用于Drupal和Roundcube邮件)。经过数小时的测试和研究,我发现了一个可重现的错误:session_set_save_handler
中定义的函数根本就没有被调用! php.ini中的设置是默认的,对我来说很好看:
session.auto_start => Off => Off
session.cache_expire => 180 => 180
session.cache_limiter => nocache => nocache
session.cookie_domain => no value => no value
session.cookie_httponly => Off => Off
session.cookie_lifetime => 0 => 0
session.cookie_path => / => /
session.cookie_secure => Off => Off
session.entropy_file => /dev/urandom => /dev/urandom
session.entropy_length => 32 => 32
session.gc_divisor => 1000 => 1000
session.gc_maxlifetime => 1440 => 1440
session.gc_probability => 0 => 0
session.hash_bits_per_character => 5 => 5
session.hash_function => 0 => 0
session.name => PHPSESSID => PHPSESSID
session.referer_check => no value => no value
session.save_handler => files => files
session.save_path => /var/lib/php5 => /var/lib/php5
session.serialize_handler => php => php
session.upload_progress.cleanup => On => On
session.upload_progress.enabled => On => On
session.upload_progress.freq => 1% => 1%
session.upload_progress.min_freq => 1 => 1
session.upload_progress.name => PHP_SESSION_UPLOAD_PROGRESS => PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix => upload_progress_ => upload_progress_
session.use_cookies => On => On
session.use_only_cookies => On => On
session.use_strict_mode => Off => Off
session.use_trans_sid => 0 => 0
调用session_start()
后,确实创建了一个会话,cookie在浏览器中设置。所以看起来很好。我创建了以下test.php来重现问题:
<?php
function sess_open($savePath, $sessionName) {
echo 'Open';
return true;
}
function sess_close() {
echo 'Close';
return true;
}
function sess_read($id) {
echo 'Read';
return true;
}
function sess_write($id, $data) {
}
function sess_destroy($id) {
}
function sess_gc($maxlifetime) {
}
echo '<pre>';
//session_write_close();
$ok = session_set_save_handler('sess_open', 'sess_close',
'sess_read', 'sess_write', 'sess_destroy',
'sess_gc');
var_dump($ok);
var_dump(session_status() === PHP_SESSION_NONE);
var_dump(session_id());
session_start();
var_dump(session_status() === PHP_SESSION_ACTIVE);
var_dump(session_id());
?>
在我的php-fpm机器上,示例输出为:
bool(true)
bool(true)
string(0) ""
bool(true)
string(26) "dkt95d9u4asqa2ge07mhors3a6"
因此,会话处理程序已正确设置。最初没有会话。在session_start()
之后,会话被创建,但不会调用sess_open()
。
我在具有完全相同配置的服务器上测试了脚本,除了使用Apche 2 Handler(又名php5_module)。输出是:
boolean true
boolean true
string '' (length=0)
OpenRead
boolean true
string 'hdcmmu34v6k1m707l8k3cutte2' (length=26)
Close
因此,调用open和read函数没有任何问题。
这可能是一个fpm错误/限制,还是我错过了什么?