PHP序列化数据存储在mysql db中

Tim*_*Tim 6 php mysql mariadb

我有基于数据库的会话存储解决方案.效果很好!但是我存在一个存储特定类型数据的问题.

我有一个使用CSRF令牌的应用程序.创建表单时,它将为该表单创建一个令牌.令牌是不同类型值的散列(sha256)值.一个副本转到表单,另一个副本存储在会话中.提交表单后,它会比较令牌以确保它们匹配.

下面是使用新数据更新db的destruct函数的示例

UPDATE session_manager SET variables= :variables  WHERE 1=1  AND id = :id
array(2) {
  [":variables"]=>
      string(152) "a:1:{s:4:"CSRF";a:1:{s:8:"register";a:2:{s:5:"token";s:64:"e749603241dec1911ef3a40d98b2f5185d389434060483297394b504cc904ede";s:4:"time";i:1443456816;}}}"
  [":id"]=>
      string(2) "49"
}
Run Code Online (Sandbox Code Playgroud)

更新声明很好,工作正常.这是我的问题,数据已更新,但您在上面的数据中可以看到的'token'值与下面的db中的值不同(这是数据的二进制下载):

a:1:{s:4:"CSRF";a:1:{s:8:"register";a:2:{s:5:"token";s:64:"b48fc79fc2f51eff765c05476895238a42d9d45b2c1aeb7c6e4582d0381b7f4f";s:4:"time";i:1443456817;}}}
Run Code Online (Sandbox Code Playgroud)

似乎mysql正在改变价值,我不能为我的生活找出问题所在.我试过的解决方案包括:

  • 连载
  • json_encode
  • BASE64

更改数据库的字符集,什么不是.在db中尝试了不同的字段类型,例如TEXT,Longtext和BLOB.哪个似乎对我不起作用:(

这是db的sql

CREATE TABLE session_manager(
    id BIGINT(11) PRIMARY KEY AUTO_INCREMENT NOT NULL,
    session_id VARCHAR(200),
    user_agent TINYTEXT NOT NULL,
    variables BLOB NOT NULL,
    initial_time DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
    regenerate_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

想到的任何理由?

小智 1

你看过time你的数组的索引吗?好像也变了。这让我认为保存会话的方法(至少)执行了两次。第二次更新会话并覆盖旧值。

在附加调试器的情况下运行此代码,或者在每次调用函数时打印/记录堆栈跟踪。当值再次更新时,这应该会给你一个很好的主意。

PS:在检索值之前,是否会在下一个请求时再次调用更新查询?