From d20e4571215b379676bf95898232717b121ad95b Mon Sep 17 00:00:00 2001 From: Dries Buytaert Date: Mon, 19 Jan 2009 10:46:52 +0000 Subject: - Patch #201122 by c960657, Moshe Weitzman: never write anonymous sessions, unless something has been written to . This is an important performance improvements -- as long as you use modules that use carefully. It might be good to report some analytics about this in the performance settings page so administrators can see if there is a 'broken' module. --- includes/session.inc | 78 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 5 deletions(-) (limited to 'includes/session.inc') diff --git a/includes/session.inc b/includes/session.inc index aae3f29ff..aa06db4ca 100644 --- a/includes/session.inc +++ b/includes/session.inc @@ -124,11 +124,10 @@ function _sess_read($key) { function _sess_write($key, $value) { global $user; - // If saving of session data is disabled or if the client doesn't have a session, - // and one isn't being created ($value), do nothing. This keeps crawlers out of - // the session table. This reduces memory and server load, and gives more useful - // statistics. We can't eliminate anonymous session table rows without breaking - // the "Who's Online" block. + // If saving of session data is disabled, or if a new empty anonymous session + // has been started, do nothing. This keeps anonymous users, including + // crawlers, out of the session table, unless they actually have something + // stored in $_SESSION. if (!drupal_save_session() || ($user->uid == 0 && empty($_COOKIE[session_name()]) && empty($value))) { return TRUE; } @@ -158,6 +157,72 @@ function _sess_write($key, $value) { return TRUE; } +/** + * Propagate $_SESSION and set session cookie if not already set. This function + * should be called before writing to $_SESSION, usually via + * drupal_set_session(). + * + * @param $start + * If FALSE, the session is not actually started. This is only used by + * drupal_session_is_started(). + * @return + * TRUE if session has already been started, or FALSE if it has not. + */ +function drupal_session_start($start = TRUE) { + static $started = FALSE; + if ($start && !$started) { + $started = TRUE; + session_start(); + } + return $started; +} + +/** + * Return whether a session has been started and the $_SESSION variable is + * available. + */ +function drupal_session_is_started() { + return drupal_session_start(FALSE); +} + +/** + * Get a session variable. + * + * @param $name + * The name of the variable to get. If not supplied, all variables are returned. + * @return + * The value of the variable, or FALSE if the variable is not set. + */ +function drupal_get_session($name = NULL) { + if (is_null($name)) { + return $_SESSION; + } + elseif (isset($_SESSION[$name])) { + return $_SESSION[$name]; + } + else { + return FALSE; + } +} + +/** + * Set a session variable. The variable becomes accessible via $_SESSION[$name] + * in the current and later requests. If there is no active PHP session prior + * to the call, one is started automatically. + * + * Anonymous users generate less server load if their $_SESSION variable is + * empty, so unused entries should be unset using unset($_SESSION['foo']). + * + * @param $name + * The name of the variable to set. + * @param $value + * The value to set. + */ +function drupal_set_session($name, $value) { + drupal_session_start(); + $_SESSION[$name] = $value; +} + /** * Called when an anonymous user becomes authenticated or vice-versa. */ @@ -211,6 +276,9 @@ function _sess_destroy_sid($sid) { db_delete('sessions') ->condition('sid', $sid) ->execute(); + // Unset cookie. + extract(session_get_cookie_params()); + setcookie(session_name(), '', time() - 3600, $path, $domain, $secure, $httponly); } /** -- cgit v1.2.3