Maintain count of logged in users without using DB or file - php

I have to maintain a count of the number of users that has been logged in. Is there any way in PHP to do it without using database or creating a file to store details ?
No framework used, just simple plain PHP.

Your options are literally, a data store or a file. You could alternatively offload them to some remote server which does something or find some sort of "remember some data" third party API, but realistically it needs to be a data store or a file.
Files would be kinda slow at this and you would get race conditions, so you'd be right to avoid those.
A MySQL Database or the like is possibly also overkill if you are not currently using one.
Another option (as #shatheesh pointed out) is Redis.
http://redis.io/commands/incr
I would suggest you do that. :)

You can achieve this using a session variable and storing count in same.
For further understanding you can visit this link :
How do I expire a PHP session after 30 minutes?

Related

Storing data into session and storing to database upon "major" action

I know there are hundreds of these questions but what I am asking however is slightly different.
When the user logs in I would like to get all their data from each table in a database and store it in a session variable (obviously not sensative data such as encrypted password/salts etc basically data that would be useless or have no value to a hacker!!), and whilst the user uses the website the relevant data stored in the session will be used as opposed to accessing the database everytime. Moreover when the data is changed or added this will be written or added to the session file, and upon a major action such as "saving" or "loggin out" the new/changed data will be written to the database.
The reason I wish to do this is simply for efficieny, I want my application to not only be fast but less resource consuming. I am no expert on either which may explain why my idea makes no differnece or is more resource intensive.
If there is an alternative to my solution please let me know or if there is something to improve on my solution I will be glad to hear it.
Thank you.
My application is using PHP and mysql.
If any of these don't apply to your app, then please ignore. In general, I'm against using sessions as caches (especially if anything in the session is going to be written back to the DB). Here's why.
Editing the session requires a request from the user. Editing a php session outside of the request-response cycle is very difficult. So if a user Alice makes a change which affects Bob, you have no way to dirty Bob's cache
You can't assume users will log out. They may just leave so you have to deal with saving info if the session times out. Again, this is difficult outside of the request-response cycle and you can't exactly leave session files lying around forever until the user comes back (php will gc them by default)
If the user requires authentication, you're storing private information in the session. Some users may not be happy about that. More importantly, a hacker could imploy that private information to conduct a social engineering attack against the end-user.
Mallory (a hacker) might not be able to use the information you put in the session, but she can poison it (ie. cache poisoning), thereby causing all sorts of problems when you write your cache to your permanent storage. Sessions are easier to poison then something like redis or memcache.
TL;DR Lots of considerations when using a session cache. My recommendation is redis/memcache.
You can also go for local-storage in HTML5, check The Guide and THE PAST, PRESENT & FUTURE OF LOCAL STORAGE FOR WEB APPLICATIONS
Local Storage in HTML5 actually uses your browsers sqlite database that works as cookies but it stores data permanently to your browser
unless someone by force remove the data from the browser finding the data files
Or if someone remove/uninstall browser completely,
or if someone uses the application in private/incognito mode of the browser,
What you need to do
Copy the schema for required tables and for required columns and update data at a regular interval
you dont have to worry about user's state, you only have to update the complete data from the localStorage to mysql Server (and from the mysql server to localStorage if required) every time user backs to your application and keep updating the data at regular interval
Now this is turning out to be more of localStorage but I think this is one of the best solution available for me.
redis is a good solution if it is available for you (sometimes developers can't install external modules for some reason) what I would do is either go with your Session approach but with encoded/encrypted and serialized data. Or, which I really prefer is to use HTML5 data properties such as:
<someElement id="someId" data-x="HiX" data-y="Hi-Y" />
which BTW works fine with all browsers even with IE6 but with some tweaks, specially if your application uses jquery and ajax. this would really be handful.
You need to use Memcache for this kind of work. To solve the problem of keeping the updated data everywhere you can create functions for fetching the data, for example when the user logs in you, authenticate the user and after that insert all the user data into the memcache with unique keys like :-
USER_ID_USERNAME for user's username
USER_ID_NAME for user's name
etc...
Now create some more functions to fetch all this data whenever you need it. For ex
function getName($user_id){
if(Memcache::get($user_id."_name"){
return Memcache::get($user_id."_name");
} else {
//Call another function which will fetch the data from the DB and store it in the cache
}
}
You will need to create functions to fetch every kind of data related to the user. And as you said you want to update this data on some major event. You can try updating the data using CRON or something like that, because as tazer84 mentioned users may never log out.
I also use what the OP described to avoid calls to db. For example, when a user logs-in, i have a "welcome-tip" on their control panel like
Welcome, <USERS NAME HERE>
If i stored only his user_id on $_SESSION then in every pageview i would have to retrieve his information from the database just to have his name available, like SELECT user_name FROM users WHERE user_id = $_SESSION['user']['user_id'] So to avoid this, i store some of his information in $_SESSION.
Be careful! When there is a change on data, you must modify the data in db and if successfull also modify the $_SESSION.
In my example, when a user edits his name (which i also store in $_SESSION so i can use it to welcome-tip), i do something like:
If (UpdateCurrentUserData($new_data)) // this is the function that modifies the db
{
$_SESSION['user']['user_name']=$new_data['user_name']; // update session also!
}
Attention to:
session.gc_maxlifetime in your php.ini
This value says how much time the $_SESSION is protected from being erased by the garbage collector (the file that exists on your disk in which the $_SESSION data are stored)
If you set this very low, users may start getting logged-out unexpectedly if they are idle more than this amount of time because garbage collector will delete their session file too quickly
if you set this very high, you may end up with lots of unused $_SESSION files of users that have left your website a long time ago.
also i must add that gc_maxlifetime works together with session.gc_probability where in general you need lower probability for high-traffic websites and bigger probability for lower traffic since for each pageview there is a session.gc_probability that garbage collector will be activated.
A nice more detailed explanation here http://www.appnovation.com/blog/session-garbage-collection-php
I know this sounds stupid but ....
If ur data is not sensitive the best way to make it accessible faster is to store it in hidden variables inside the forms itself. You can save comma separated or values in an array.

Alternative to Huge Codeigniter session data

I have seen many similar questions on the overflow, but none of them really addressed my scenario hence I am opening this question.
I am working on a project where there is database of thousands of mp3 tracks and mixes. Each mp3 file has an id and associated information on database. Now a shopping cart is being build in a way that user can select tracks and add to the cart. When a track is being added to cart its id is stored in the session and this works fine.
Now the problem arrives when there is large number of id's stored in a session. A session being a cookie [codeignitor] , I know it has 4kb of storage.
What will be the best practice to get this data preserved? I know that I have to change my strategy and move out of using session.
I tried using database [mysql], its not only slower but also has several issues, like each new user need to have a row added to database tables, how to clear these tables after use.. etc etc.
I tried using memcached but I believe that is not the right choice since the data that I am trying to store is not that huge. Also memcached has several issues on windows platform, provided I am not sure if the client will deploy it on a linux / windows server.
I need a native cross platform solution. I have done quiet a lot of research and did not find a reliable solution yet.
I use codeigniter framework, hence you can suggest any PHP or codeigniter solutions, thanks much.
You talk about storing things "in the session" so I assume you're using PHP's session handler, not setting cookies individually.
In this case, the session storage is all done on the server side, so a 4k limit does not apply. Take a look at your http headers during a request, and you will see only something like this:
Set-Cookie: PHPSESSID=1234abcde56789f
This session ID refers to a file (typically stored in a directory, e.g. /var/lib/php/session/ on RHEL distros) which contains the actual data as a serialized PHP object.
Why dont you try setcookie() function in php?
you can store as much amount of data you want in the cookie,and store the refrence to the session in database!
hope you will understand my answer!
what miken32 is saying is correct. And if you are using Codeigniter, then set up a session database table and use codeigniter sessions. if you use a db table then its just an id which is set on the cookie. be sure and start with the official codeigniter session db table so it works properly.
codeigniter session class has built in 'garbage collection'.
all explained here, scroll down for the database portion:
http://ellislab.com/codeigniter/user-guide/libraries/sessions.html
Using a native PHP session is the right way to move, as the fellow users answered a php session stores only id on to cookie, But codeignitor behaves differently, it stores all the data on to cookie and this is where the catch is.
Moving on to normal PHP session was a pain because I have to change the codes allover the project. After a little research and testing I have come to a conclusion that [Native Session library for CI][1]
[1]: https://github.com/EllisLab/CodeIgniter/wiki/Native-session by Derek Jones is an awesome alternative to use PHP sessions over CI with the same CI session functions and syntax.
So to conclude , Either use PHP sessions from the scratch or use this library as an alternative to overcome CI session size Limitations.

Where to keep the globals variables in PHP?

I am used to use Java and Spring Framework. But not so long ago I started learning PHP , to get familiar with another kind of language.
I am trying to write a simple thing for drawing using html canvas, so more then 1 user can use that at the same time to draw.
In Java i would use a class variable in controller to store the picture draw by users. And every 1-2 seconds users send the request with the new data they have drawn, so i can add the changes to the global variable. and then send the changes to every user. When a new user enters, the server sends the whole picture to him.
So, my question is, how can i store an application global variable in PHP? like in this example with picture...
As i see, after finishing, the PHP halts and all the variables die with it, right? So is there any way to make a variable application global? So i can get access to it from different parts of application?
I can save it to text file before finishing the script. and every time new request happens, read it again from text file, make changes and then write back to text file... but it's so crazy... isn't there any way just like in Spring Framework and Java that i used before?
You need a form of persistent storage. By persistent, I mean storage that is not based on an individual user's session like the $GLOBALS array is. PHP Sessions are useful for storage for a single user, but one user cannot access the session data of another user.
Persistent storage can be achieved a few ways. Some options: checking a row in a database table or storing a value in a file like you mentioned.
Database storage
Check out php's mysqli_query() for more information on doing this via a database. This will require knowledge of MySQL syntax.
File storage
Check out php's file_get_contents() and file_put_contents() for examples on how to easily interact with retrieving data from files and setting data in files.
As DevZer0 answered - you want to use sessions. More information about session you will find in the php manual: http://www.php.net/manual/en/intro.session.php

Best practice for storing global data in PHP?

I'm running a web application that allows a user to log in. The user can add/remove content to his/her 'library' which is displayed on a page called "library.php". Instead of querying the database for the contents of the users library everytime they load "library.php", I want to store it globally for PHP when the user logs in, so that the query is only run once. Is there a best practice for doing this? fx. storing their library in an array in a session?
Thanks for your time
If you store each user's library in a $_SESSION as an array, as you suggested (which is definitely possible) you will have to make sure that any updates the user makes to the library are instantly reflected to that session variable.
Honestly, unless there is some seriously heavy querying going on to fetch a library, or you have tons of traffic, I would just stick to 'execute query whenever the user hits library.php'.
Consider the size of the data. Multiply that by the maximum number of concurrent users.
Then compare that the to memory avaiable on your server. Also consider whether or not this is a shared server; other sites needs resources too.
Based on this, it is probably best to either create a file that can be used (as per Remi's comment), or remain in the default stateless form and read every time. I doubt that reading the data each time is creating much of an overhead.
When the user login you can generate a xml file (USER_ID.xml for instance) that you display with xslt.
http://php.net/manual/en/book.xslt.php
Each PHP script dies when it completes, so data can not be kept permanentely live in a web application as you would do in a PC application.
One way could be sessions, but it depends on the amount of data you want to save. According to your example you are talking about a library, so it sounds to me like big quantity of data need to be saved, in such case the DB is the way to go, and yes you have to query it each time.
Another way could be to save them in an array inside a php file, but in the same way you have to query the DB each time, you would have to include such php file each time.
Since this is a db performance optimization, I would suggest that you take a look at memcached which matches your problem perfectly:
memcached is [..] intended for use in speeding
up dynamic web applications by
alleviating database load.
I think it would be best to store it in a Session.
It the user logs in, the Session is being created and you can save data in it using the superglobal:
$_SESSION['key'] = "value";
You can also store Arrays or everything else there and it can be cleared if the user logs out.
you care for performance; Please note:
Session may use database or file to store data.
database is here to be used instead of files, for it's performance and abilities.
use database, it is designed to be used exactly in such situations!

Replace PHP Sessions

I have a social network type app I have been working on for at least 2 years now, I need it to scale well so I have put a lot of effort into perfecting the code of this app. I use sessions very often to cache database results for a user when a user logs into the site I cache there userID number, username, urer status/role, photo URL, online status, last activity time, and several other things into session variables/array. Now I currently have 2 seperate servers to handle this site, 1 server for apache webserver and a seperate server for mysql. Now I am starting to use memcache in some areas to cut down on database load.
Now my sessions are stored on disk and I know some people use a database to store sessions data, for me it would seem that storing session data that I cached from mysql would kind of defeat the purpose if I were to switch to storingsessions in mysql. SO what am I missing here? Why do people choose to use a database for sessions?
Here are my ideas, using a database for sessions would make it easiar to store and access sessions across multiple servers, is this the main reason for using a database?
Also should I be using memcache to store temp variables instead of storing them into a session?
PHP has the ability to use memcached to store sessions.
That may just be the winning ticket for you.
Take a look at this google search.
One part of the Zend Server package is a session daemon.
Be careful using memcache for that purpose. Once the memory bucket is full, it starts throwing away stuff in a FIFO fashion.
Found this on slideshare about creating your own session server with php-cli.
The single best reason to store sessions in the database is so you can load-balance your website. That way it doesn't matter which server hands out the next page because they are all using the same database for storing their sessions.
Have a look at PHP's set_save_handler() for how to install a custom session handler. It takes about 30 lines to set one up that puts the session in the database, though that doesn't count the lines to make a decent database handler. :-) You will need to do:
ini_set('session.save_handler', 'user');
ini_set('session.auto_start', '0');
... although session.auto_start will need to be in your php.ini (and set to 0).
If the database access is going to be a bit expensive, there are some other things you can do to mitigate that. The obvious one is to have a DB server that is just for sessions. Another trick is to have it poke stuff into both memcache and the DB, so when it checks, if the memcache record is missing, it just falls back to the DB. You could get fancy with that, too, and split the session up so some of it is in memcache but the rest lives in the database. I think you'd need to put your own access functions on top of PHP's session API, though.
The main reason to store session data in a database is security because otherwise you have no way to validate it. You'd store the session ID along with the data in the database and match them to see if the session has been tampered with but you can't use the server's (apache) default session mechanism anymore.
For Storing variables in memcache instead of the session.. have you set up your database query cache? I'd have a look there instead first as it's far easier to deal with than with memcache.

Categories