Welcome Guest, Not a member yet? Register   Sign In
CI 3 using native sessions instead of driver
#1

Would this be the best way to use the native php sessions instead of using their drivers? Since their drivers are just wrappers around session functions; I figured this would be the easiest way to do it still preserving library interface

The reason behind this is I am having issues with locking with mysql database driver and redis driver. I want to use native php sessions and swap in a redis driver at the php level.

This seems to work well. Any thoughts?

 
PHP Code:
<?php
    
class MY_Session extends CI_Session 
    
{
        public function __construct(array $params = array())
        {
            $CI =& get_instance();
                    
            
// No sessions under CLI
            if (is_cli())
            {
                log_message('debug''Session: Initialization under CLI aborted.');
                return;
            }
            elseif ((bool) ini_get('session.auto_start'))
            {
                log_message('error''Session: session.auto_start is enabled in php.ini. Aborting.');
                return;
            }
            
            
// Configuration ...
            $this->_configure($params);
            $this->_config['_sid_regexp'] = $this->_sid_regexp;
    
            
// Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers
            if (isset($_COOKIE[$this->_config['cookie_name']])
                && (
                    is_string($_COOKIE[$this->_config['cookie_name']])
                    OR ! preg_match('#\A'.$this->_sid_regexp.'\z#'$_COOKIE[$this->_config['cookie_name']])
                )
            )
            {
                unset($_COOKIE[$this->_config['cookie_name']]);
            }
    
            session_start
();
    
            
// Is session ID auto-regeneration configured? (ignoring ajax requests)
            if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) OR strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest')
                && ($regenerate_time config_item('sess_time_to_update')) > 0
            
)
            {
                if ( ! isset($_SESSION['__ci_last_regenerate']))
                {
                    $_SESSION['__ci_last_regenerate'] = time();
                }
                elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time))
                {
                    $this->sess_regenerate((bool) config_item('sess_regenerate_destroy'));
                }
            }
            // Another work-around ... PHP doesn't seem to send the session cookie
            // unless it is being currently created or regenerated
            elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id())
            {
                setcookie(
                    $this->_config['cookie_name'],
                    session_id(),
                    (empty($this->_config['cookie_lifetime']) ? time() + $this->_config['cookie_lifetime']),
                    $this->_config['cookie_path'],
                    $this->_config['cookie_domain'],
                    $this->_config['cookie_secure'],
                    TRUE
                
);
            }
            $this->_ci_init_vars();        
        }
    
Reply
#2

You will probably have the same locking issues with the native session extension. You probably need to spend some time figuring out where to use session_write_close() and to adjust the database to handle more connections and release them faster.

Persistent connections will not help.

Give serious consideration to using file-based sessions.
Reply
#3

(12-12-2019, 08:32 AM)dave friend Wrote: You will probably have the same locking issues with the native session extension. You probably need to spend some time figuring out where to use session_write_close() and to adjust the database to handle more connections and release them faster.

Persistent connections will not help.

Give serious consideration to using file-based sessions.

phpredis extension has much finer grain control with locking; so it should perform just as good as mysql GET_LOCK without database load. You can do the following. (microseconds instead of 1 second).

; Should the locking be enabled? Defaults to: 0.
redis.session.locking_enabled = 1
; How long should the lock live (in seconds)? Defaults to: value of max_execution_time.
redis.session.lock_expire = 60
; How long to wait between attempts to acquire lock, in microseconds (µs)?. Defaults to: 2000
redis.session.lock_wait_time = 50000
; Maximum number of times to retry (-1 means infinite). Defaults to: 10
redis.session.lock_retries = 10

My main question though is if I implemented native sessions correctly? Also I cannot use file based sessions as the application is behind a load balancer on multiple web servers.
Reply
#4

(12-12-2019, 08:35 AM)blasto333 Wrote: phpredis extension has much finer grain control with locking; so it should perform just as good as mysql GET_LOCK without database load. You can do the following. (microseconds instead of 1 second).

; Should the locking be enabled? Defaults to: 0.
redis.session.locking_enabled = 1
; How long should the lock live (in seconds)? Defaults to: value of max_execution_time.
redis.session.lock_expire = 60
; How long to wait between attempts to acquire lock, in microseconds (µs)?. Defaults to: 2000
redis.session.lock_wait_time = 50000
; Maximum number of times to retry (-1 means infinite). Defaults to: 10
redis.session.lock_retries = 10

My main question though is if I implemented native sessions correctly? Also I cannot use file based sessions as the application is behind a load balancer on multiple web servers.

Do you understand that CI 3 uses "native" sessions?  Do you realize the main purpose of the CI_Session library is to provide database drivers? PHP does not have any built-in ability to use databases. To do that it is necessary to write a custom session handler, i.e. the CI_Session class and its associated drivers.

You cannot solve the locking issue by removing the locks. (Well, you can, but it would be bad practice.) It's not clear to me that's what you have in mind, but if it is read this. If you have read that before then read it again more carefully.
Reply
#5

(This post was last modified: 12-12-2019, 09:03 AM by blasto333.)

(12-12-2019, 09:00 AM)dave friend Wrote:
(12-12-2019, 08:35 AM)blasto333 Wrote: phpredis extension has much finer grain control with locking; so it should perform just as good as mysql GET_LOCK without database load. You can do the following. (microseconds instead of 1 second).

; Should the locking be enabled? Defaults to: 0.
redis.session.locking_enabled = 1
; How long should the lock live (in seconds)? Defaults to: value of max_execution_time.
redis.session.lock_expire = 60
; How long to wait between attempts to acquire lock, in microseconds (µs)?. Defaults to: 2000
redis.session.lock_wait_time = 50000
; Maximum number of times to retry (-1 means infinite). Defaults to: 10
redis.session.lock_retries = 10

My main question though is if I implemented native sessions correctly? Also I cannot use file based sessions as the application is behind a load balancer on multiple web servers.

Do you understand that CI 3 uses "native" sessions?  Do you realize the main purpose of the CI_Session library is to provide database drivers? PHP does not have any built-in ability to use databases. To do that it is necessary to write a custom session handler, i.e. the CI_Session class and its associated drivers.

You cannot solve the locking issue by removing the locks. (Well, you can, but it would be bad practice.) It's not clear to me that's what you have in mind, but if it is read this. If you have read that before then read it again more carefully.

I know it uses native session and has custom handlers; but I still want to be able to use methods such as set_userdata which is why I create MY_Session.php and removed the linking of session handling to drivers. Then I can enable phpredis session extension in php.ini

I don't want to remove the lock just make it not lock as long as php CI redis driver does (1 second for 30 tries). I am asking if what I did in MY_Session.php seems sufficient.
Reply
#6

(This post was last modified: 12-14-2019, 10:08 AM by dave friend.)

I still think the best idea is to determine where in your scripts to use session_write_close(). It would also be smart to be discriminate about when and where to load (and thereby, start) the session library.

You probably know everything that's here, but read it anyway.
Reply
#7

All my pages are behind a login page and I do session_write_close in places I can
Reply




Theme © iAndrew 2016 - Forum software by © MyBB