UPDATE: This is the second of a three part series on CodeIgniter, Redis, and Socket.IO integration. Please be sure to read the other posts as well.
Part 1: A Sample CodeIgniter Application with Login And Session
Part 2: You are here.
Part 3: Live Updates in CodeIgniter with Socket.IO and Redis
In my effort to add awesome real-time live updates to a plain ol’ CodeIgniter application, I decided to move the session information usually stored in a database table to a key-value store – namely, Redis. Not only does this alleviate some load from the MySQL database, but it also provides an easy way to expose user session data to a NodeJS server. This will be important in the future when adding Socket.IO.
The process for converting my existing application to use Redis rather than MySQL was painfully simple. It was pretty much just a handful of step-by-step instructions via the command line, and voila! PHP and Redis! BFFs 4Ever!
Here were the basic steps I followed:
1. Install Redis
Simply follow the instructions on in the Redis quickstart guide. These instructions were written for linux, and should work on most distributions. It might work on a Mac, but I’m not sure. Windows… you’re on your own. Below is the tl;dr version with just the commands.
tar xvzf redis-stable.tar.gz
cd redis-stable
make
cd src
sudo cp redis-server /usr/local/bin/
sudo cp redis-cli /usr/local/bin/
sudo mkdir /etc/redis
sudo mkdir /var/redis
sudo cp utils/redis_init_script /etc/init.d/redis_6379
sudo cp redis.conf /etc/redis/6379.conf
sudo mkdir /var/redis/6379
From the Redis Quickstart Guide:
Edit the configuration file, making sure to perform the following changes:
Set daemonize to yes (by default it is set to no).
Set the pidfile to /var/run/redis_6379.pid (modify the port if needed).
Change the port accordingly. In our example it is not needed as the default port is already 6379.
Set your preferred loglevel.
Set the logfile to /var/log/redis_6379.log
Set the dir to /var/redis/6379 (very important step!)
/etc/init.d/redis_6379 start
Boom. Done.
2. Install phpredis
PHP needs an extension to talk to Redis. There are a few options for this listed on the Redis site. I went with phpredis by mainly because it is required for the My_Session class used below. It’s also a great project that is still updated frequently.
To install, follow the directions in the README for your system. The default directions worked just fine for me.
phpize
./configure [--enable-redis-igbinary]
make && make install
Then add extension=redis.so
to /etc/php5/apache2/php.ini and /etc/php5/cli/php.ini (if you are using Apache on linux). Finally, restart Apache.
Done, son.
3. Configure CodeIgniter to use Redis for session data storage
Finally, we just drop one class into the application’s library folder, and add a couple of lines to the config file to get everything working.
Really. That’s it. I’m not joking. It’s that easy.
Grab the MY_Session.php class from Ming Zhou’s gist: https://gist.github.com/zhouming/3672207 and drop it into /application/libraries. CodeIgniter will automatically use it as a subclass of Session. Most of the essential functions are overridden by My_Session so that Redis is used to store session data that will be used to authenticate user sessions while the application is running. The only thing left is to add the following two lines to /application/config/config.php:
$config['redis_port'] = '6379';
Obvously you will need to change ‘localhost’ to the IP address of your Redis server if it is on a different machine from your application.
And that’s it! The application is Redis ready!
Note: I’ve added the MY_Session class and some installation notes to the ci_sock project in my GitHub repo, just in case the links become broken or you want an easy reference.
June 10, 2013 at 7:52 am
Hi Eric,
Thanks for the wonderful post and the marvelous utility that you have created. Please help me to understand the following two points
1) Why do we need to set $config[‘sess_use_database’] to TRUE? I went through the file MY_Session.php. This parameter is only read at the beginning and not used anywhere
2) Won’t it be a good idea to set sess_use_redis like $config[‘sess_use_redis’] = TRUE within config.php and then use it accordingly within MY_Session.php
Finally, please pardon me for asking this stupid question
Since, you have given the filename as MY_Session.php, will it override, the default behaviour of Session Class?
Thanks
June 10, 2013 at 11:19 am
@Avirup:
1. $config[‘sess_use_database] is a config variable used by the CodeIgniter framework. It must be set to true so CodeIgniter will know that the Session class needs to be used. See: http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
2. CodeIgniter uses the convention of prepending ‘MY_’ to a base class to override default behavior (so MY_Session overrides Session). You still need $[‘sess_use_database’] so that CodeIgniter will know to use MY_Session.
June 10, 2013 at 1:08 pm
Hi Eric,
From Code Igniter site,
$[‘sess_use_database’]
Once enabled, the Session class will store session data in the DB.
In this case, we don’t want to store the session in DB. Instead, we want to store it in redis.
If we set $[‘sess_use_database’] to True, then we need to create a table by name of ci_sessions as well, or whatever specified under $config[‘sess_table_name’]
So, I am little confused
June 10, 2013 at 5:07 pm
Redis is substituting for the database, so it needs to be set to true. You do not need $config[‘sess_table_name], as it is used in Session, but not MY_Session.
If you try setting $[‘sess_use_database’] = false, does it break?
June 11, 2013 at 12:38 am
No, it works perfectly fine, even if $[‘sess_use_database’] = false. I have verified by setting it to true as well. You don’t require to have the ci_session table created in the database, if you are using MY_Session.
So, basically it is immaterial whether you keep $[‘sess_use_database’] = true or false, when using MY_Session
Thanks for the the utility. It is really helpful.
September 3, 2013 at 4:11 pm
Hi Eric,
Fatal error: Class ‘Redis’ not found in /opt/lampp/htdocs/ci_sock/part_three/application/libraries/MY_Session.php on line 33
Am getting in this error can u advice me
September 6, 2013 at 9:27 am
Im getting the same problem…
September 6, 2013 at 11:55 am
@filipe and @punith
Did you install phpredis outlined in Step 2? That error indicates that the Redis class in PHP is not present.
September 7, 2013 at 2:18 pm
@eterps
yup i followed the tutorial and installed all the stuff it tells to install :s
September 10, 2013 at 9:07 pm
Why ? Why use Reddis instead of mysql ? people are viewing this tut because they want to learn about live updates using socket.io , not bc they want to use some weird knock off data storage no ones heard of ? why complicate ur tut with new tech ? you should make a seperate tut with a focus on socket.io updates using all the default technologys ( mysql, php , codeigniter) and none of the reddis stuff
September 18, 2013 at 2:14 pm
@chuck If you read the entire series, you’ll realize that Redis is required for information to be easily shared between Socket.IO and CodeIgniter. MySQL is still used for all CodeIgniter data storage for the application.
March 27, 2014 at 11:58 am
Hi Eric,
your post is wonderful i’m follow and work ok, i have one question : do you know about this error:
A PHP Error was encountered
Severity: Notice
Message: Redis::setex() [redis.setex]: send of 344 bytes failed with errno=32 Broken pipe
Filename: libraries/GT_Session.php
Line Number: 155
Fatal error: Uncaught exception ‘RedisException’ with message ‘Connection lost’ in /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/GT_Session.php:259 Stack trace:
#0 /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/GT_Session.php(259): Redis->multi()
#1 /home/tihms/public_html/developer/nucleo_ci_no_tocar/libraries/Session.php(500): GT_Session->sess_write()
#2 /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/Ion_auth.php(336): CI_Session->unset_userdata(‘username’)
#3 /home/tihms/public_html/developer/gestion_2_carpeta_principal/controllers/auth.php(122): Ion_auth->logout()
#4 [internal function]: Auth->logout()
#5 /home/tihms/public_html/developer/nucleo_ci_no_tocar/core/CodeIgniter.php(359): call_user_func_array(Array, Array)
#6 /home/tihms/public_html/developer/index.php(201): require_once(‘/home/tihms/pub…’)
#7 {main} thrown in /home/tihms/public_html/developer/gestion_2_carpeta_principal/libraries/GT_Session.php on line 259
is posible any configuration that i have wrong?
This error happend when i try to star a session, or when i try to close session, but is some time, not all time, and node report the next error:
Error: Ready check failed: ERR max number of clients reached
at RedisClient.on_info_cmd (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:317:35)
at Command.callback (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:365:14)
at RedisClient.return_error (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:500:25)
at ReplyParser. (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:260:14)
at ReplyParser.EventEmitter.emit (events.js:95:17)
at ReplyParser.send_error (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/lib/parser/javascript.js:293:10)
at ReplyParser.execute (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/lib/parser/javascript.js:176:22)
at RedisClient.on_data (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:476:27)
at Socket. (/home/tihms/public_html/developer/assets/nodejs/node_modules/redis/index.js:79:14)
at Socket.EventEmitter.emit (events.js:95:17)
so can you helpme?
Thanks
May 20, 2014 at 1:55 pm
Hi,
Fatal error: Uncaught exception ‘RedisException’ with message ‘Can’t connect to localhost:6379’ in C:\xampp\htdocs\ci_sock\part_three\application\libraries\MY_Session.php:34 Stack trace: #0 C:\xampp\htdocs\ci_sock\part_three\application\libraries\MY_Session.php(34): Redis->connect(‘localhost’, ‘6379’) #1 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(1099): MY_Session->__construct() #2 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(938): CI_Loader->_ci_init_class(‘Session’, ‘MY_’, NULL, NULL) #3 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(216): CI_Loader->_ci_load_class(‘session’, NULL, NULL) #4 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(1178): CI_Loader->library(‘session’) #5 C:\xampp\htdocs\ci_sock\part_three\system\core\Loader.php(152): CI_Loader->_ci_autoloader() #6 C:\xampp\htdocs\ci_sock\part_three\system\core\Controller.php(51): CI_Loader->initialize() #7 C:\xampp\htdocs\ci_sock\part_three\system\core\CodeIgniter.php(308): CI_Controller->__construct() #8 C:\xampp\h in C:\xampp\htdocs\ci_sock\part_three\application\libraries\MY_Session.php on line 34
I have error, please help me. thanks
June 2, 2014 at 11:49 pm
Hi Eric,
Thanks for this tutorial. However, I have a few concerns:
1. Codeigniter has a problem with session cookies, whereby, login sessions are randomly destroyed and users are logged out repeated with time as they use the application.
Does, Redis, being an in-memory system help solve this problem.
2. I have an application that uses flexi-auth for user-authentication which has its own table in the database and does seem to need the ci_session table, do you think Redis will have issues with flexi-auth authentication or its database table.
Thanks in advance
June 24, 2015 at 1:51 am
Fatal error: Class ‘Redis’ not found in /var/www/xxx/application/libraries/MY_Session.php on line 33
How can i solve this problem. redis installed in my system.
January 23, 2018 at 3:03 am
Fatal error: Class ‘Redis’ not found in C:\xampp\htdocs\part_three\application\libraries\MY_Session.php on line 33