| Server IP : 156.238.232.47 / Your IP : 216.73.216.150 Web Server : nginx/1.25.3 System : Linux C202504152095410 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 User : www ( 1000) PHP Version : 8.3.25 Disable Function : passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,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,imap_open,apache_setenv MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /www/data/wwwroot/2026_08_17_01/core/basic/ |
Upload File : |
<?php
/**
* @copyright (C)2016-2099 Hnaoyun Inc.
* Memcache 会话处理器(兼容 PHP 8.x 内置 memcache session 写入异常)
*/
namespace core\basic;
class MemcacheSessionHandler implements \SessionHandlerInterface
{
private $memcache;
private $servers;
public function __construct($path)
{
$this->servers = self::parseServers($path);
if (! $this->servers) {
error('memcache 会话 session.path 格式错误,示例:tcp://127.0.0.1:11211');
}
self::assertReachable($this->servers);
}
public function open($savePath, $sessionName)
{
$this->memcache = new \Memcache();
foreach ($this->servers as $server) {
$this->memcache->addServer($server['host'], $server['port']);
}
if (! self::ping($this->memcache)) {
error('Memcached 服务连接失败,请确认服务已启动且 session.path 配置正确(当前:' . self::formatServerList($this->servers) . ')');
}
return true;
}
public function close()
{
return true;
}
public function read($id)
{
$data = $this->memcache->get($id);
return ($data === false) ? '' : $data;
}
public function write($id, $data)
{
$lifetime = (int) ini_get('session.gc_maxlifetime');
if ($lifetime <= 0) {
$lifetime = 1440;
}
return $this->memcache->set($id, $data, 0, $lifetime);
}
public function destroy($id)
{
return $this->memcache->delete($id);
}
public function gc($maxlifetime)
{
return 0;
}
// 启动前检测 Memcached 是否可达
protected static function assertReachable(array $servers)
{
$memcache = new \Memcache();
foreach ($servers as $server) {
$memcache->addServer($server['host'], $server['port']);
}
if (! self::ping($memcache)) {
error('Memcached 服务连接失败,请确认服务已启动且 session.path 配置正确(当前:' . self::formatServerList($servers) . ')');
}
}
// 探测 Memcached 连通性
protected static function ping(\Memcache $memcache)
{
$stats = $memcache->getStats();
if (is_array($stats)) {
foreach ($stats as $stat) {
if (is_array($stat) && isset($stat['pid'])) {
return true;
}
}
}
$key = '__pboot_sess_ping_' . mt_rand();
if ($memcache->set($key, '1', 0, 5)) {
$memcache->delete($key);
return true;
}
return false;
}
protected static function formatServerList(array $servers)
{
$addrs = array();
foreach ($servers as $server) {
$addrs[] = $server['host'] . ':' . $server['port'];
}
return implode('; ', $addrs);
}
// 解析 memcache 会话服务器地址,支持 tcp://host:port 与 host:port,多节点以 ; 分隔
protected static function parseServers($path)
{
$servers = array();
$path = trim($path);
$path = rtrim($path, ';');
foreach (explode(';', $path) as $entry) {
$entry = trim($entry);
if ($entry === '') {
continue;
}
if (preg_match('#^tcp://([^:]+):(\d+)$#i', $entry, $match)) {
$servers[] = array(
'host' => $match[1],
'port' => (int) $match[2]
);
} elseif (preg_match('#^([^:]+):(\d+)$#', $entry, $match)) {
$servers[] = array(
'host' => $match[1],
'port' => (int) $match[2]
);
}
}
return $servers;
}
}