Sol*_*rac 5 php postgresql session
使用自定义会话处理程序在postgreSQL服务器上保存会话时,打开一个第二个postgres连接,如果存在任何unicode字符,会话将中断!
这是我的自定义会话处理程序:
class custom_session_handler implements SessionHandlerInterface {
protected $nombre_de_sesion, $tiempo_de_vida, $db;
public function open($savePath, $sessionName) {
$this->db = pg_connect("host=**** port=5432 dbname=**** user=**** password=***") or die('Imposible conectar con la base de datos de sesiones');
$this->gc(time());
$this->nombre_de_sesion = trim($sessionName);
$this->tiempo_de_vida = pg_escape_literal(time() + 2500);
return (isset($this->nombre_de_sesion) && strlen($this->nombre_de_sesion) > 2) ? true : false;
}
public function close() {
return pg_close($this->db);
}
public function destroy($session_id) {
return pg_affected_rows(pg_query($this->db, 'DELETE FROM "sesiones_soporte" WHERE session_id = ' . pg_escape_literal($session_id) . '')) ? true : false;
}
public function write($session_id, $session_data) {
$escaped_id = pg_escape_literal($session_id);
$escaped_session = pg_escape_literal(pg_escape_bytea($session_data));
if (pg_affected_rows(pg_query($this->db, 'UPDATE "sesiones_soporte" SET "session_expira" = ' . $this->tiempo_de_vida . ', "session_byte"=' . $escaped_session . ' WHERE session_id = ' . $escaped_id . ' AND session_expira > ' . (int) time())) == 1) {
return true;
} else {
pg_query($this->db, 'INSERT INTO "sesiones_soporte" ("session_id", "session_expira", "session_byte") VALUES (' . $escaped_id . ', ' . $this->tiempo_de_vida . ', ' . $escaped_session . ' )');
return true;
}
return false;
}
public function read($session_id) {
$escaped_id = pg_escape_literal($session_id);
$sesion = pg_unescape_bytea(pg_fetch_result(pg_query($this->db, 'SELECT session_byte FROM "sesiones_soporte" WHERE session_id = ' . $escaped_id . ' AND session_expira > ' . (int) time() . ' LIMIT 1'), 0, 'session_byte'));
!isset($sesion) ? : pg_query($this->db, 'UPDATE "sesiones_soporte" SET "session_expira" = ' . $this->tiempo_de_vida . ' WHERE session_id = ' . $escaped_id . ' AND session_expira > ' . (int) time());
return (isset($sesion) ? $sesion : false);
}
public function gc($maxlifetime) {
return pg_affected_rows(pg_query($this->db, 'DELETE FROM "sesiones_soporte" WHERE session_expira < ' . (int) $maxlifetime));
}
}
Run Code Online (Sandbox Code Playgroud)
在我们的会话中启动我们的处理程序
$handler = new custom_session_handler();
session_set_save_handler($handler, true);
session_name('my_session');
session_start();
Run Code Online (Sandbox Code Playgroud)
并将一些数据保存到我们的会话中:
$_SESSION['test'] = 'áéíóúñ';
Run Code Online (Sandbox Code Playgroud)
此时你可以var_dump()在你的会话中找到你想要的所有内容,它可以正常工作,你可以刷新页面,它会保持会话信息,它会起作用但是留在我这里...
好吧,我需要检查冰箱:
$seccond_server = pg_connect("host=#### port=#### dbname=#### user=#### password=######### or die("No bueno on db #2");
print_r($_SESSION);
Run Code Online (Sandbox Code Playgroud)
哦,会话数据似乎没问题但是......等等...... 现在你的会话已经破了!
重新加载页面,您将获得: PHP Warning: session_start(): Failed to decode session object. Session has been destroyed in some location at some line
再次重新加载页面将为您提供: PHP Warning: pg_fetch_result(): Unable to jump to row 0 on PostgreSQL result index something in some path:
您可以播放评论并取消注释该秒数pg_connect,只要您不这样做,会话就会起作用pg_connect
更新:
我忘了提到相同的代码在PHP 5.6.2上完美运行
我将此问题添加为对PHP错误跟踪系统的评论,因为我发现了类似的内容:https: //bugs.php.net/bug.php?id = 70584
如果有人想关注和/或更新它,我只填写了一个PHP错误报告:https://bugs.php.net/bug.php?id = 71088
客户端和服务器信息:
FIRST SERVER(会话存储):x86_64-unknown-linux-gnu上的PostgreSQL 9.4.4,由gcc(GCC)4.4.7 20120313(Red Hat 4.4.7-11)编译,64位
SECCOND服务器:x86_64-redhat-linux-gnu上的PostgreSQL 8.4.20,由GCC gcc(GCC)4.4.7 20120313(Red Hat 4.4.7-11)编译,64位
CLIENT(php):PostgreSQL(libpq)版本9.4.4
当涉及到 postgres 9 和 postgres 8 时, BYTEA 转义使用不同的转义方法,并且 PHP 不会在类级别隔离 pg_ 行为。
您需要传递正确的数据库链接作为第一个参数,pg_escape_bytea()以便它可以使用正确的转义方法:
pg_escape_bytea($this->db, $data);
Run Code Online (Sandbox Code Playgroud)
另一方面pg_unescape(),不会将您的数据库链接作为参数。
当然,您可以将会话信息包装起来base64(),然后将其转义为 bytea。稍后您将需要取消转义并打开它。
转义方法似乎在处理多字节字符串的方式上有所不同,因此,base64 字符串不会产生任何错误。
额外信息:
负责 php bug 票证的yohgaki指出了我的会话处理程序上的不同错误,他还发布了使用外部数据库实现良好的会话处理程序的示例。如果您有兴趣,完整的详细信息在这里:https ://bugs.php.net/bug.php?id=71088