在PHP 7.0中使用各种PHP框架会话驱动程序时存在错误。我最初在使用CodeIgniter数据库驱动程序时遇到了这个问题,并假设它是一个CodeIgniter问题,但后来在多个会话驱动程序和多个框架上经历过它。在这一点上,我已经安全地得出结论,会话驱动程序的类型是无关紧要的 - 看似随机,应用程序将崩溃,日志(我已经尝试过Apache和php-fpm + nginx)填满了以下内容:
PHP致命错误:session_start():无法初始化存储 module:user(路径:[无论我在php.ini路径中有什么])
我使用的驱动程序不使用php.ini中设置的值,无论我是否在php.ini中将session.save_handler设置为files,redis等,而不管我设置的路径(Redis服务器,如果redis) ,启用文件的完全可写文件夹)发生错误。除非在框架之外的php文件中调用本机“session_start()”,否则永远不应该触发此处的路径。此外,在框架之外调用“session_start()”工作正常......所以很明显PHP可以访问路径。就好像在某些时候,会话驱动程序变成了框架驱动程序和php.ini中设置的混合体。 session.save_handler的错误消息总是有“user”,所以显然不是从php.ini中提取的......但路径是。为什么会这样?这是一个难以描述的问题之一,直到你经历过......并且它很难重现,因为即使数百个会话(直到它突然停止工作),一切似乎都能正常工作。重新启动Apache也无法解决问题 - 这里有许多问题,我最终只是重新启动机器以避免停机。显然PHP 7机器现在将从负载平衡器轮换中退出......但我希望现在可以解决问题。
我遇到过PHP 7.0 RC5,RC6和& RC8在我自己以及Ubuntu 15.10 Wily上的最新OndřejSurýPPA编译(7.0.0-2 + deb.sury.org~wily + 1)。我在CodeIgniter& amp; Symfony,并且遇到了问题,无论框架中使用的驱动程序类型(文件,数据库,redis)还是php.ini中设置的session.save_handler(再次,这应该与此无关,但只是认为应该提到)。我一直在尝试组合并在野外扔东西,这个问题每次都会发生(有时需要12个小时以上,具体取决于网站的流量)。
感谢您提供的任何帮助!我愿意接受建议并愿意在这一点上尝试任何事情。
答案 0 :(得分:6)
当会话处理程序的open()
函数未返回布尔值TRUE时,会发生此错误,这显然意味着某种失败。
可能无法连接到数据库,无法打开文件,不存在的目录等等 - 这取决于会话处理程序实际使用的内容。
答案 1 :(得分:6)
函数_open应返回true以避免此错误。
无论我们使用数据库还是文件,它都不能为null或为空。
当我们使用数据库来存储会话数据时,我们将其保留为空或不返回布尔值。这是造成这个错误的主要原因。
class session_handler
{
public function __construct()
{
session_set_save_handler(
array($this, "_open"),
array($this, "_close"),
array($this, "_read"),
array($this, "_write"),
array($this, "_destroy"),
array($this, "_gc")
);
}
public function _open($savePath, $sessionId)
{
return true;
}
public function _close() { }
public function _read($id) { }
public function _write($id, $data) { }
public function _destroy($id) { }
public function _gc($max) { }
}
仅适用于PHP 7.我不知道它是否是一个bug。
答案 2 :(得分:1)
这通常是由于会话无法连接到它使用的任何驱动程序(文件,数据库)。
我通过查看config.php
文件
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
因为我使用了数据库,这意味着它由于某种原因无法连接! (对于文件,它可能没有写入缓存文件的权限)
接下来我打开了日志
$config['log_threshold'] = 4;
4 = All Messages
...然后刷新页面,现在我在application/logs
中有一个名为log-#.php
的文件,其中#
是日期。
INFO - 2017-08-30 10:05:41 --> Database Driver Class Initialized
ERROR - 2017-08-30 10:05:41 --> Severity: Warning --> mysqli::real_connect(): (HY000/1045): Access denied for user 'user'@'localhost' (using password: YES) /var/system/database/drivers/mysqli/mysqli_driver.php 202
ERROR - 2017-08-30 10:05:41 --> Unable to connect to the database
ERROR - 2017-08-30 10:05:41 --> Severity: Warning --> mysqli::real_connect(): (HY000/1045): Access denied for user 'user'@'localhost' (using password: YES) var/system/database/drivers/mysqli/mysqli_driver.php 202
ERROR - 2017-08-30 10:05:41 --> Severity: Error --> session_start(): Failed to initialize storage module: user (path: ci_sessions) /var/system/libraries/Session/Session.php 140
所以我只是确保用户可以访问数据库并且工作正常。
答案 3 :(得分:1)
在我的情况下,我使用PHP ver 5.6
和CI ver 3.4
(Codeigniter)
服务器:BIGROCK
我在我的实时服务器中发现了这些问题。
然后很久以后。我只是想删除我的数据库并重新创建它。
然后我才知道我没有权限用户访问数据库。
因此,当您完成创建数据库和用户后,您应该向用户授予访问数据库的权限(previlleges)。
让我知道你的情况是否有用。谢谢。
答案 4 :(得分:0)
我改变了我的php.ini:
session.save_path = "N;/path" **to** session.save_path = "/tmp"
然后我重启我的php7-fpm
答案 5 :(得分:0)
我相信我已经弄明白了这个问题;我将结束这个问题。基本上,似乎当框架会话驱动程序/配置发生问题(超出sql连接,Redis的内存不足等问题)时,它将恢复尝试使用php.ini中设置的sess.save_path,同时仍然使用框架会话驱动程序因此,除非框架驱动程序与php.ini中的默认sess.save_path兼容,否则会发生此错误。对我来说,恢复到php.ini中的sess.save_handler也更有意义......但如果这是一个问题,那么应用程序配置存在更大的问题需要解决。
这不是错误本身会破坏会话......这是框架会话驱动程序的潜在问题。我感到愚蠢......但是原木基本上让我陷入了疯狂的追逐。重启nginx或Apache无法解决问题,因为问题出在其他地方。我相信仍然可以使用可用的PHP 7 Redis库解决问题,SQL问题是我的错。看似尝试了一些组合并获得相同的结果后,问题显得更加神秘。我在PHP 7上使用Redis会话时仍然会遇到奇怪的错误,但就像我说的那样,PHP 7 Redis库还不是很成熟。
答案 6 :(得分:0)
我们遇到了类似的问题,我们使用session_set_save_handler
设置我们自己的自定义处理程序以转到memcached,但一直收到此错误:
Warning: session_write_close(): Failed to write session data (user). Please verify that the current setting of session.save_path is correct (/var/lib/php/7.0/session) in Unknown on line 0
原来,"写"函数需要返回一个布尔值(就像start一样),但它是session_set_save_handler的唯一函数,它没有提到官方PHP文档中的任何返回值。因此,虽然看起来它恢复到默认会话处理程序,但它只是为默认会话处理程序提供错误。
错误和文档页面永远不会让我们找到解决方案......
答案 7 :(得分:0)
仅当session_save_path无效时才会发生这种情况,如果您将会话数据存储在数据库中,则必须创建会话表,以便CI保存数据,否则您将最终遇到此错误。希望帮助了某人
答案 8 :(得分:0)
我决定迁移系统并进行一些非常需要的更新。我使用Codeigniter 3和php 7.2遇到了这个问题。找到问题后,我意识到这是多么荒谬,想知道我怎么不早点解决。
无论如何,这至少对我来说是解决方案。
确保已安装memcacheD:
sudo apt-get update
sudo apt-get install php7.2-memcached
如果这样做很好,那么我们可以继续检查其他所有内容。
在Codeigniter的配置文件“ /application/config/config.php”中,有一个部分可以指定会话选项:
$config['sess_driver'] = 'memcached';
$config['sess_cookie_name'] = 'some_session_name';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = NULL;
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
我需要更改的行是以下行:
$config['sess_save_path'] = NULL;
确保将其设置为CI3手册中记录的有效路径。 正确的设置如下所示:
$config['sess_driver'] = 'memcached';
$config['sess_save_path'] = 'localhost:11211';
确保更改“ localhost”以反映您的内存缓存服务器位置。
有关更多信息,请参见-Codeignier Session Manual
也可以在这里查看:php memcacheD Sessions support
如果页面上的评论被删除,我将在此发布:
如果您想使用'memcacheD'扩展而不是'memcache'(有 两个不同的扩展)以进行会话控制,您应该支付 注意修改php.ini
Google的大多数网络资源都基于内存缓存,因为它是 比memcacheD更早的版本。他们会说如下
session.save_handler =内存缓存session.save_path = “ tcp:// localhost:11211”
但是对于memcacheD来说无效
您应该像这样修改php.ini
session.save_handler =内存缓存session.save_path =“ localhost:11211”
看,没有协议标识符
为了进行测试,我这样做是为了使用户知道php本身在访问memcacheD时没有问题:
session_start();
header('Content-Type: text/plain');
session_start();
if(!isset($_SESSION['visit']))
{
echo "This is the first time you're visiting this server\n";
$_SESSION['visit'] = 0;
}
else
echo "Your number of visits: ".$_SESSION['visit'] . "\n";
$_SESSION['visit']++;
echo "Server IP: ".$_SERVER['SERVER_ADDR'] . "\n";
echo "Client IP: ".$_SERVER['REMOTE_ADDR'] . "\n";
print_r($_COOKIE);
$servers = explode(",", ini_get("session.save_path"));
$c = count($servers);
for ($i = 0; $i < $c; ++$i) {
$servers[$i] = explode(":", $servers[$i]);
}
$mem = new memcached();
$mem->addServer('127.0.0.1', '11211', '1');
$mem->set('011', 'Hello There');
print_r($mem->get('011'));
print_r($mem->getAllKeys());
这使我看到memcacheD运行正常。
在您的php.ini中,还有一些选项可供您注意。只需搜索[session]或session.save_path。 CI3表示它不使用php.ini文件中的此选项,但是如果您打算在框架之外使用memcacheD并保持一致性,则可能需要进行设置。
这开始于php.ini文件的〜1327行:
[Session]
; Handler used to store/retrieve data.
; http://php.net/session.save-handler
session.save_handler = memcached
; Argument passed to save_handler. In the case of files, this is the path
; where data files are stored. Note: Windows users have to change this
; variable in order to use PHP's session functions.
;
; The path can be defined as:
;
; session.save_path = "N;/path"
;
; where N is an integer. Instead of storing all the session files in
; /path, what this will do is use subdirectories N-levels deep, and
; store the session data in those directories. This is useful if
; your OS has problems with many files in one directory, and is
; a more efficient layout for servers that handle many sessions.
;
; NOTE 1: PHP will not create this directory structure automatically.
; You can use the script in the ext/session dir for that purpose.
; NOTE 2: See the section on garbage collection below if you choose to
; use subdirectories for session storage
;
; The file storage module creates files using mode 600 by default.
; You can change that by using
;
; session.save_path = "N;MODE;/path"
;
; where MODE is the octal representation of the mode. Note that this
; does not overwrite the process's umask.
; http://php.net/session.save-path
;session.save_path = "/var/lib/php/sessions"
session.save_path = "locahost:11211"
另一个检查设置的地方是mecacheD服务器配置文件。根据系统的不同,其位置可能有所不同。对我来说,它位于 / etc / 目录下。
/etc/memcached.conf
图片供我参考:
答案 9 :(得分:0)
我必须将代码点火器升级到最新版本才能解决此问题。
运行:
CentoOS: 7.6.1810
Mysql: 8.0.15
PHP: PHP 7.3.4
我尝试了很多操作,例如将会话从数据库移动到文件和Memcached。没事。修复它的唯一一件事就是从CI 3.0到3.1,然后像预期的那样蓬勃发展。
希望它可以帮助某人。
答案 10 :(得分:0)
只需将/ your-Codeigniter-project / system / cache的权限及其内容更改为0777即可。由于缺少权限,它实际上无法创建会话文件。使用以下命令sudo chmod 0777 /your-Codeigniter-project/system/cache
sudo chmod 0777 /your-Codeigniter-project/system/cache/*
注意:将上面的“您的Codeigniter-项目”替换为您的项目路径。
答案 11 :(得分:0)
1-使用phpinfo()查找默认的会话tmp文件夹(session.save_path);在yourdomain.com上 2通过SSH连接到主机 3转到tmp父文件夹$ cd / home / abc / xyz 4 chmod 777 -R tmp
答案 12 :(得分:0)
此错误是由于未定义的会话路径引起的。
打开 application/config/config.php 行号。 383.
替换下面的行
$config['sess_save_path'] = NULL;
与
$config['sess_save_path'] = APPPATH . 'cache/session/';
不要忘记授予缓存/会话文件夹的写入权限。