简体   繁体   中英

How do I set the session cookie path in cakePHP while still saving session data in the database?

By default cakePHP puts the session cookie at the application level. For instance, if you have a cakePHP application at www.mydomain.com/myapp the cookie is stored at "/myapp". I need my session data available to other applications at www.mydomain.com, so I would like to have the session cookie stored at "/" instead.

I found a bunch of articles on how to do this, but when using the methods explained in both of these popular posts/guides, it disables sessions being saved in the database.

How to bend CakePHP's session handling to your needs

cakePHP - Cookbook - Sessions

Does anyone know how to change the session cookie path to "/" while still being able to save session data in the database?

Thanks!

Can this not be done at the PHP level rather than in CakePHP itself?

So you can use session_set_save_handler() (man page) in the following sort of way to achieve sessions stored in the database. The following code is from a comment on the PHP manual page by maria at junkies dot jp and I have not specifically tested it:

<?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);

?>

So you could reference that in your bootstrap file.

Basically, sessions in a normal server should be global by default. At least have been in all servers, that I have used.. So I would actually change my server before some hardcore work-around in the script.

However, if you are using some session related class, that has __destruct() function at the end..and in it, you have session_destroy(); OR it doesn't really matter, where the session_destroy(); sits, but it does matter for your path related issue. I ran some quick tests and sessions by default are global within the domain...however, on the second page obviously the variable isn't being displayed, if the trigger page kills it.

My test:

trigger.php file:

<?

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 file:

<?

session_start();

echo $_SESSION['foo'];

?>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM