如何在仍保存数据库中的会话数据的同时在cakePHP中设置会话cookie路径?

时间:2011-08-31 22:27:02

标签: php session cakephp session-cookies

默认情况下,cakePHP将会话cookie放在应用程序级别。例如,如果您在www.mydomain.com/myapp上有cakePHP应用程序,则cookie将存储在“/ myapp”中。 我需要将我的会话数据提供给www.mydomain.com上的其他应用程序,所以我希望将会话cookie存储在“/”中。

我发现了一些关于如何执行此操作的文章,但是当使用这两个热门帖子/指南中解释的方法时,它会禁用保存在数据库中的会话。

How to bend CakePHP's session handling to your needs

cakePHP - Cookbook - Sessions

有没有人知道如何将会话cookie路径更改为“/”,同时仍然可以在数据库中保存会话数据?

谢谢!

2 个答案:

答案 0 :(得分:0)

这不能在PHP级别而不是在CakePHP本身中完成吗?

因此,您可以使用session_set_save_handler() (man page)以下列方式来实现存储在数据库中的会话。以下代码来自对PHP manual page by maria at junkies dot jp的评论,我没有专门测试它:

<?php
class Session
{

    /**
     * a database connection resource
     * @var resource
     */
    private $_sess_db;

    /**
     * Open the session
     * @return bool
     */
    public function open() {

        if ($this->_sess_db = mysql_connect(SESSION_DB_HOST,
                                            SESSION_DB_USER,
                                            SESSION_DB_PASS)) {
            return mysql_select_db(SESSION_DB_DATABASE, $this->_sess_db);
        }
        return false;

    }

    /**
     * Close the session
     * @return bool
     */
    public function close() {

        return mysql_close($this->_sess_db);

    }

    /**
     * Close the session
     * @return bool
     */
    public function close() {

        return mysql_close($this->_sess_db);

    }

    /**
     * Read the session
     * @param int session id
     * @return string string of the sessoin
     */
    public function read($id) {

        $id = mysql_real_escape_string($id);
        $sql = sprintf("SELECT `data` FROM `sessions` " .
                       "WHERE id = '%s'", $id);
        if ($result = mysql_query($sql, $this->_sess_db)) {
            if (mysql_num_rows($result)) {
                $record = mysql_fetch_assoc($result);
                return $record['data'];
            }
        }
        return '';

    }

    /**
     * Write the session
     * @param int session id
     * @param string data of the session
     */
    public function write($id, $data) {

        $sql = sprintf("REPLACE INTO `sessions` VALUES('%s', '%s', '%s')",
                       mysql_real_escape_string($id),
                       mysql_real_escape_string($data),
                       mysql_real_escape_string(time()));
        return mysql_query($sql, $this->_sess_db);

    }

    /**
     * Destoroy the session
     * @param int session id
     * @return bool
     */
    public function destroy($id) {

        $sql = sprintf("DELETE FROM `sessions` WHERE `id` = '%s'", $id);
        return mysql_query($sql, $this->_sess_db);

}

    /**
     * Garbage Collector
     * @param int life time (sec.)
     * @return bool
     * @see session.gc_divisor      100
     * @see session.gc_maxlifetime 1440
     * @see session.gc_probability    1
     * @usage execution rate 1/100
     *        (session.gc_probability/session.gc_divisor)
     */
    public function gc($max) {

        $sql = sprintf("DELETE FROM `sessions` WHERE `timestamp` < '%s'",
                       mysql_real_escape_string(time() - $max));
        return mysql_query($sql, $this->_sess_db);

    }

}

//ini_set('session.gc_probability', 50);
ini_set('session.save_handler', 'user');

$session = new Session();
session_set_save_handler(array($session, 'open'),
                         array($session, 'close'),
                         array($session, 'read'),
                         array($session, 'write'),
                         array($session, 'destroy'),
                         array($session, 'gc'));

// below sample main

session_start();
session_regenerate_id(true);

?>

所以你可以在你的bootstrap文件中引用它。

答案 1 :(得分:0)

基本上,普通服务器中的会话默认情况下应该是全局的。至少已经在所有服务器中,我已经使用过..所以我实际上会在脚本中的一些硬核解决之前更改我的服务器。

但是,如果你正在使用一些与会话相关的类,那末尾有__destruct()函数,那么你有session_destroy();或者它并不重要,session_destroy( );坐着,但它对你的路径相关问题很重要。我运行了一些快速测试,默认情况下会话在域中是全局的...但是,在第二页上显然没有显示变量,如果触发页面杀死它。

我的测试:

trigger.php文件:

<?

session_start();

echo $_SESSION['foo'] = 'bar';

// session_destroy(); <- This kills it
// Otherwise $_SESSION['foo'] gets displayed on the child.php file in test/ directory

?>

test / child.php文件:

<?

session_start();

echo $_SESSION['foo'];

?>