what's the best way to save sessions in a database? - php

i'm planning on making my own custom session handling functions. i want to save it in the database but i have some doubts.
is it viable or will just slow down my app?
i have to save the session after each set or can i just save it all at once? because i had this idea to put this function in the class destructor method. so, when the program ends, it will save the data in the database.
but how can i use my other class (database class) for this, being sure it won't be destructed before the session class?
if the user quits the connection and the app stops running, the destructor will still be called?
so, what do you guys think? what do you suggest me to do?

I use DB sessions all the time with Zend and Symfony so its definitely viable, there will be a cost of course but most likely nothing significant.
Normally the way these handlers work is to use session_set_save_handler that way it works as normal except for the actual function called which writes the data. However pay attention to the warnings about object destruction.

Yes it will normally be slightly slower than PHP's native session handler, however it shouldn't be noticeable. This is unless you are having problems with file locking issues (like Windows does)

Why would you want to permanently store session data?
Usually people use different session handlers to make application faster (we use memcache for sessions, because our application is quite complex and distributed and we want it to run fast). I consider this requirement as bad application design, if you want to track your visitors in some way, there are a lot of better ways doing it. Or you are using session for the things it is not quite intended/suitable for. Of course i can imagine that there might be that kind of requirement, just i dont think that this is the case.

Related

Is it a good practice to save an object in a session?

I'm developing a generic app on PHP that is dynamically customized for many clients.
I have the class client, where I load the style and preferences for the client.
My question is:
Is it a good practice to save that object in a session? (I think that is the best solution instead of creating the object in each page, that will need lots of mysql querys.
There are few things you need to consider while you deal with session.
You should not store vary large values in session.
i think this is not a problem in your case as preferences are usally small enough.
When you store object in session. you might not get realtime updates. as for example lets say same user is logged in using two separate browsers and/or machines and modify preferences in one. in this case other one will not have the updated customization. its not a big problem but depends on your requirements.
I don't see any other problem here. in fact its valid and good solution to store small values in session and avoid db queries.
if it's something that won't change, and will just result in constantly calling MySQL queries over and over then yes, that is a good idea.
MySQL queries (and functions in general) are memory/cpu intensive and can affect page load speeds for the PHP, so the less work you are causing it to do the better.
if the returned values are going to be changing constantly it would be better not to, but store what values you can in the session.
I think the session will die when client close the browser.
If you store it in cookie (Loaded client) ? it not good for security.
When you store mini data in session (Loaded server).that mean you are using some memory at server.
What happen at the time you have many client ?
So, the database connection should be destroy at the end of process for each page.
Don't worry to use it.

How Can We Stop Our Widgets From Dying Under Heavy Load?

I've inherited a php/js project that creates audio-playing widgets. The requirement is really that they be able to stand up to some pretty heavy load at "peak times": when a new track is first announced there may be a lot of people rushing to play it at once.
Unfortunately, the widgets tend to do pretty badly under such stressful conditions. We had considered that saving and looking up an access key in a SQLite database might have been causing fatal errors due to locking. Experimentally I changed the access keys to be stored in session variables, but I'm now worried this may just be creating a new kind of bottleneck: does every request have to wait for the session to free up before it can go ahead?
I downloaded Pylot and did some basic load tests: it doesn't take many agents trying to access the same widget to make it glitchy or completely unusable, maybe 10 or 20. Ideally we'd like to be able to handle a considerably greater volume of traffic than this. What strategies can I sensibly adopt to be able to field many times more requests?
A PHP file-based session will lock the session file until the script exits, or you call session_write_close(). You can do a quick session_start(); session_write_close(). The $_SESSION array will still be available, but any subsequent changes will NOT be written to disk, as PHP has been told the session is closed.
Store your session into a database that does only locking while wrtiing on the concrete session id (primary key that is) in a database that is supporting MVCC, like MySQL and the InnoDB backend. You can further optimize this by improving the file-system beneath it.
This done you might run into race-conditions but not into lockings. Have fun!

What things should be saved in SESSION and what should not be?

I give one example why this question appears in my head:
Lets say i create class 'PDOstart' which extends PDO class. On class 'PDOstart' all variables needed for PDO is defined on private section (like host, user, password and ect). So it makes very easy to use PDO class like:
$con = new PDOstart();
$con->query("SELECT ... ");
Because on my webpage I use only one DB I begin thinking why not add PDOstart object into SESSION? like: $_SESSION['db'] = $con; ? So i don't need on every page do "new PODstart". But I'm not sure that will be good idea...
Is there anything what i should avoid add to $_SESSION (for security or performance reason)?
user id so that every time the page loads you know what use is browsing, meta data such as timespan from page changes (Bot Detect), Local information, User template selection. anything that's required for that session really.
As you stated $con let me explain something.
There are several variable types in php and the main ones are:
strings
boolean's
integer's
objects
arrays
resources
Now you can store all of them into the sessions apart from resources, as there such things as file handles, connections to external entities there only open for the time it takes the page to be processed by PHP, then there closed.
the others are ok as there stored in the memory and are static as such, they will not change unless you programmatically change them.
The main entites you should store in the session are
GUID: So that you can track what user is logged in.
Flash Data: So if your doing a redirect you will be able to show a error message on the other page.
Browser Data, so that you can compare that the browser that is currently browsing is the same as the last, this way you can kill the session fro security.
Things like Database Data such as User Rows should not be stored in the session and you should create a separate cache mechanism to do this for you.
You can store your PDOstart class in the session, as long as you keep this in mind:
When you do $_SESSION['key'] = $obj, you actually serialize the object (assuming default php session handler, that happens when the data is flushed).
When you do this to a 'resource', such as a database connection, there is every likelihood the connection will not persist.
To workaround such cases, php has the __sleep and __wakeup magic methods
I would assume your PDOstart class will ensure connection to PDO on both __construct and __wakeup, doubling the complexity.
However, there's another reason for not doing it that way: the session might go away at any moment, so you shouldn't really rely on any information being there. Surely you can place safeguards, which would re-initialize everything, but that again is adding unneeded complexity.
There's no golden rule (at least that I'm aware of) that explicitly states you should keep as little info as possible in your sessions, but it seems to be a fairly common approach. I'd keep a user id and probably an access token. There's not much stopping you to do it otherwise tho.
As for security, this kind of use shouldn't really matter, as long as the session as a whole is secure. They never truly are, but it's a whole different topic.
Short answer: good things to store - user id, bad things to store - everything else.
Some complement to the good response of RobertPitt you should really add an autoloader if you start storing objects in the session.If the class of your object is not available you'll get a standard broken objet if you do not have an autoload mecanism for class loading.
Then, depending on how your session are stored you should be careful of the size they take. let's say you store it on a very fast drive or on a memcached service, you do not need to worry too much about the fact that this file will be read for every request of your user. If you have slow IO on your drive be careful. Now if you store your session in a database you may care about the insert/update/delete rythm on the session table, some databases (think about MySQL) are not very god at handling an high write load on one table.
In term of security you do not have to worry too much about session storage as it is on the server. At least if you (the admin) use disk storage you should ensure that all handled application are not using the same directory for session storage, if not the weaker application will define you security level for sessions.

Should I not call a method multiple times if I don't have to?

I currently use sessions pretty heavy and I am re-coding my network site right now. 1 thing I have done is made a session class that has some simple methods for example here is how I would retrieve session data using my class.
$session = new Session();
// to set a session I would use this
echo $session->set('user_id');
// to view a session's data
echo $session->get('user_id');
Now this is basicly the same as setting a viewing a session variable the regular way except I run it through this session class, the purpose I have is to make it more flexible. I figure if all session data is ran through that class on a big site, then all I would have to do to change it's source to use a cache or memcache or a database is to just change the session class file.
SO in reality I really don't have much gain in using a class/methods for my session data at the moment but some day I might.
My question is, on a very high traffic site, would it be better to not be making the extra method/class call everytime I need to show sessions data?
Don't prematurely optimize. Chances are you will have inefficiencies or algorithm problems that cost seconds at a time, so stop worrying about saving a millisecond here or there.
You are using a pattern that is exemplified in several frameworks, one of which is the framework I personally use, Zend Framework.
The comments about optimization are correct, the performance hit of the session stuff you are doing is liable to be so minute that it wouldn't matter in the end. There are numerous benefits that having a session class can provide for you, and the frameworks common use of a session object as opposed to simple session access via functions should show that clearly.
Regards,
You're fine. You want to use static or some other persistent variable on data that can be cached during the life of the request but in general on high performance sites the backend code is usually not the thing you have to worry about.
Check out this article for what I mean about backend performance.

PHP; use sessions or re-use query?

I'm interested in what is the more efficient way of handling user data in my game. When someone is playing the game, data from the server will constantly need to be queried from the database.
So I want to know if it is more efficient to keep querying the database or to store the data from the first query in a session and then keep using the session every time I need the data.
This is probably a stupid question as I think it is going to be sessions that are better, but it's best to be 100% sure :)
If the data will only be updated by the client session in question, then sure, cache it in the session. If other processes will be updating it, then you need to either reobtain it from the database or work out some method for invalidating your session's cached version.
Shared state goes in the database, unless you are ready to manage shared access yourself, which is a big pain.
Often-updated user-specific state goes into the session (if you issue an UPDATE every time anyone presses a key in your game, your database is dead).
If you need a superfast session architecture, try memcached.
Using sessions will be more efficient. But (assuming the data in the session as cache) any other script not invoked by the user, which updates the dataset you're using, should invalidate the cache somehow.
This means that the cache (now maitained in a session) should be accessible to other scripts. So it might be easier to maintain the cache in files (or you could use php_apc or memcached) instead of sessions.
I think there are many caching classes that are good but the only experience I have is with Zend_Cache and it is really easy to use. It supports APC, memcached, file, etc as backends (a.k.a storage)

Categories