【发布时间】:2016-12-24 03:09:06
【问题描述】:
我认为问题的根源在于我对字符串处理的理解。 serialize($_SESSION) 做同样的事情。我的会话文件持续了 5kb,但是当我将 session_encode() 输出到日志或数据库时,它会在大约 100 个字节后中断。
$s = session_encode();
$n = strlen($s);
error_log("Session ($n): $s");
我明白了:
会话 (5948):return_url|s:30:"https://solution-locale/Moneys";complete|s:0:"";basket|O:15:"SolutionUBasket":22:{s:13:
当我尝试将值写入数据库时(pg_execute()--这是一个准备好的语句),我遇到了同样的问题。但是当我执行bin2hex() 时,我了解到在最后一个“:”之后有一个空字符(0x00)。
很明显,问题出在字符串处理上,而我做得不对。
而写db的代码如下:
pg_prepare($this->getCnx(), $token, $sql);
pg_execute($this->getCnx(), $token, $values);
$sql 是:
UPDATE "solution_ubasket_temp" SET ("session_id", "session", "id") = ($1, $2, $3) WHERE "id"=$4"
$values 只是一个数组。对其进行strlen() 操作确认所有5kb 都进入会话成员。
更新继续进行,没有错误消息,但“会话”字段被切断,就像调试中的一样。
select length(session), * from solution_ubasket_temp
确认“会话”在 105 个字节后被截断。
“会话”列是 text,但将其更改为 bytea 并没有帮助。
select octet_length(session), * from solution_ubasket_temp
确认。
我在 Debian 8.5 上运行 PHP 5.6。
【问题讨论】:
-
PHP 手册警告您
error_log函数:Warning error_log() is not binary safe. message will be truncated by null character.(php.net/manual/en/function.error-log.php) -
@JeremyHarris 不,我从来没有收到过警告
-
@Opux 警告写在php手册页上。
-
发帖
var_dump("Session ($n): $s");怎么样?? -
不确定这是否拼写得足够清楚,所以为了避免在此处走错方向:序列化数据包含
NUL字节。这本身不是需要解决的问题。仅:1)error_log尤其无法正确处理NUL字节,这就是您的调试方法失败的原因; 2) Postgres 可以处理NUL字节就好了如果你正确处理它们。你必须向我们展示你到底在用pg_execute做什么我们将帮助您解决这部分问题。
标签: php string postgresql session