【问题标题】:session_set_save_handler write function is not called on gcloudgcloud 上未调用 session_set_save_handler 写入函数
【发布时间】:2021-07-05 21:24:21
【问题描述】:

我在标准模式下使用 php 在谷歌云平台上运行应用程序。 我使用session_set_save_handler将会话存储在mysql数据库中。

.php 文件

...
$mysqli = new mysqli($config->host, $config->user, $config->password, $config->db, $port, $socket);

// test connection, works fine.
$mysqli->query("INSERT INTO `sessions` (`ID`, `SessionID`, `Data`, `DateTouched`) VALUES (NULL, 'aaa1', 'aa1', '21')");

$CurrentTime = time();

function sess_open($sess_path, $sess_name) {

    echo "session open - sess_path: " . $sess_path . "session_name " . $sess_name . "<br />";
    return true;
}

function sess_close() {
    echo "session close" . "<br />";
    return true;
}
    ...
    function sess_write($sess_id, $data) {
        GLOBAL $mysqli;
    
        echo 'session write';// never called
    
        $CurrentTime = time();
        $mysqli->query("UPDATE sessions SET Data = '$data', DateTouched = $CurrentTime WHERE SessionID = '$sess_id';");
        return true;
    }
    ...

    session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");
    session_start();
    
    $_SESSION['foo'] = "bar";
    $_SESSION['baz'] = "wombat";
    
    $s_w_c = session_write_close();
    var_export($s_w_c); // false on gcloud

它在我的本地系统 (MAMP) 上运行良好,但在 google 上没有调用 write 函数。其他功能正常。 有什么想法吗?

谢谢。

【问题讨论】:

  • 您的代码对于 sql 注入易受攻击的,因此请使用 带参数的准备好的语句参见stackoverflow.com/questions/60174/…
  • @nbk 谢谢,我会解决的。
  • mysqli 连接正常吗?日志中有任何错误(github.com/php/php-src/blob/master/php.ini-production#L97)?
  • 是的,没关系,将数据写入数据库(我已经更新了问题,测试查询工作正常)。
  • 我怀疑 $_SESSION 在云平台上是否可信——它与单个服务器上的单个 Web 服务器实例绑定。

标签: php mysql session gcloud session-set-save-handler


【解决方案1】:

我不知道为什么它会在您的本地机器上运行。可能是旧版本的 PHP 或没有调试文本?

启动时会话发生的情况是:

session_start() -> open() -> read() -> all_green?真:假;

您在 open 函数中使用了 echo,因为 session_start() 需要在任何输出之前调用,它会失败并关闭会话。内部检查位于读取功能之后。下面是一个简单的测试代码:

class Session implements SessionHandlerInterface {

    public function __construct(&$mysql) { }

    function open($path, $name) {
        //echo "session open" . PHP_EOL;
        return true;
    }

    function close() {
        echo "session close" . PHP_EOL;
        return true;
    }

    function write($id, $data) {
        echo 'session write' . PHP_EOL;
        return true;
    }

    function read($id) { 
        //echo "session read" . PHP_EOL;
        return ""; 
    }

    function destroy($id) {
        echo "session Destroy" . PHP_EOL;
        return true;
    }

    function gc($lifetime) {
        echo "session gc" . PHP_EOL;
        return true;
    }
}
    $dummy_connection = true;
    session_set_save_handler(new Session($dummy_connection), true);
    session_start();
    
    $_SESSION['foo'] = "bar";
    $_SESSION['baz'] = "wombat";
    
    $s_w_c = session_write_close();
    var_export($s_w_c);

注释的回显会导致启动失败。

【讨论】:

    【解决方案2】:

    如果数据被正确写入数据库,那么它无法在写入处理程序中看到回显输出的原因是,正如documentation 中所述,此处理程序直到输出之后才会执行流已关闭,因此调试语句的输出将永远不会在浏览器中看到。

    如果您需要调试输出,建议将调试输出写入文件作为更好的做法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-07
      • 2013-03-16
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      相关资源
      最近更新 更多