PHP Session-like storage global across all users - php

What is a good method to retain a small piece of data across multiple calls of a PHP script, in such a way that any call of the script can access and modify its value - no matter who calls the script?
I mean something similar to $_SESSION variable, except session is strictly per-client; one client can't access another client's session. This one would be the same, no matter who accesses it.
Losing the value or having it corrupted (e.g. through race conditions of two scripts launched at once) is not a big problem - if it reads correctly 90% of the time it's satisfactory. OTOH, while I know I could just use a simple file on disk, I'd still prefer a RAM-based solution, not just for speed, but this running from not very wear-proof flash, endless writes would be bad.

Take a look at shared memory functions. There are two libraries that can be used to access shared memory:
Semaphores
Shared Memory
For storing binary data or one huge String, the Shared Memory library is better, whereas the Semahpores library provides convenient functions to store multiple variables of different types (at the cost of some overhead, that can be quite significant especially for a lot of small-sized (boolean for example) variables.
If that is too complex, and/or you don't worry about performance, you could just store the data in files (after all, PHPs internal session management uses files, too....)

A good alternative to using a database would be memcache!

Related

Storing userdata in $_SESSION vs. repeated DB accesses

There is certain userdata read from the (MySQL) database that will be needed in subsequent page-requests, say the name of the user or some preferences.
Is it beneficial to store this data in the $_SESSION variable to save on database lookups?
We're talking (potentially) lots of users. I'd imagine storing in $_SESSION contributes to RAM usage (very-small-amount times very-many-users) while accessing the database on every page request for the same data again and again should increase disk activity.
The irony of your question is that, for most systems, once you get a large number of users, you need to find a way to get your sessions out of the default on-disk storage and into a separate persistence layer (i.e. database, in-memory cache, etc.). This is because at some point you need multiple application servers, and it is usually a lot easier not to have to maintain state on the application servers themselves.
A number of large systems utilize in-memory caching (memcached or similar) for session persistence, as it can provide a common persistence layer available to multiple front-end servers and doesn't require long time persistence (on-disk storage) of the data.
Well-designed database tables or other disk-based key-value stores can also be successfully used, though they might not be as performant as in-memory storage. However, they may be cheaper to operate depending on how much data you are expecting to store with each session key (holding large quantities of data in RAM is typically more expensive than storing on disk).
Understanding the size of session data (average size and maximum size), the number of concurrent sessions you expect to support, and the frequency with which the session data will need to be accessed will be important in helping you decide what solution is best for your situation.
You can use multiple storage backends for session data in PHP. Per default its saved to files. One file for one session. You can also use a database as session backend or whatever you wan't by implementing you own session save handler
If you want your application most scalable I would not use sessions on file system. Imagine you have a setup with mutiple web servers all serving your site as a farm. When using session on filesystem a user had to be redirected to the same server for each request because the session data is only available on that servers filesystem. If you not using sessions on filesystem it would not matter which server is being used for a request. This makes the load balancing much easier.
Instead of using session on filesystem I would suggest
use cookies
use request vars across multiple requests
or (if data is security critical)
use sessions with a database save handler. So data would be available to each webserver that reads from the database (or cluster).
Using sessions has one major drawback: You cannot serve concurrent requests to the user if they all try to start the session to access data. This is because PHP locks the session once it is started by a script to prevent data from getting overwritten by another script. The usual thinking when using session data is that after your call to session_start(), the data is available in $_SESSION and will get written back to the storage after the script ends. Before this happens, you can happily read and write to the session array as you like. PHP ensures this will not destroy or overwrite data by locking it.
Locking the session will kill performance if you want to do a Web2.0 site with plenty of Ajax calls to the server, because every request that needs the session will be executed serially. If you can avoid using the session, it will be beneficial to user's perceived performance.
There are some tricks that might work around the problem:
You can try to release the lock as soon as possible with a call to session_write_close(), but you then have to deal with not being able to write to the session after this call.
If you know some script calls will only read from the session, you might try to implement code that only reads the session data without calling session_start(), and avoid the lock at all.
If I/O is a problem, using a Memcache server for storage might get you some more performance, but does not help you with the locking issue.
Note that the database also has this locking issue with all data it stores in any table. If your DB storage engine is not wisely chosen (like MyISAM instead of InnoDB), you'll lose more performance than you might win with avoiding sessions.
All these discussions are moot if you do not have any performance issues at all right now. Do whatever serves your intentions best. Whatever performance issues you'll run into later we cannot know today, and it would be premature optimization (which is the root of evil) trying to avoid them.
Always obey the first rule of optimization, though: Measure it, and see if a change improved it.

Static object that is accessible to all users like Application.cfc

I've done a fair bit of PHP over the years but I'm currently learning ColdFusion and have come across the Application.cfc file.
Basically this is a class that's created once (has an expire date). The class handles incoming users and can set session variables and static memory objects, such as queries. For example I can load site wide statistical data for one user in another thread from the Application.cfc. Something that would usually take a few seconds for each page would make the whole site quick and responsive.
Another example (just for clarification).
If I put an incremental variable that's set to 0 in OnApplicationStart this variable can be incremented with each user request (multiple users) or in OnSessionStart without the need to contact the SQL database since it's constantly in the server's memory under this application.
I was wondering if PHP has a similar file or object? Something that can be created once and used to store temporary variables?
The PHP runtime itself initializes the environment from scratch on every HTTP request, so it has no built-in mechanism to do this. Of course you can serialize anything into common storage and then read it back and deserialize on each request, but this is not the same as keeping it in-memory.
This type of functionality in PHP is achieved by outsourcing to other programs; memcached and APC are two of the most commonly used programs that offer such services, and both come with PHP extensions that simplify working with them.

Using PHP $_SESSION variable to store large amonts of data

I'm currently storing a fair amount of data in the $_SESSION variable. I'm doing this so I don't need to keep accessing the database.
Should I be worried about memory issues on a shared server?
Can servers cope with large amounts of data stored in the $_SESSION variable?
Should I be worried about memory issues on a shared server?
Yes - session data is loaded into the script's memory on every request. Hence, you are at risk of breaking the individual per-script memory limit. Even if you don't hit the limit, this is really inefficient.
Accessing data from the database on demand is much better.
.. in addition to what #Pekka wrote:
PHP sessions an not alternative to a caching solution !
You should investigate if your server has APC available. You should use that on top of layer which accesses information from database (assuming you actually have an OO code).

Using $_Session variables with high traffic

I am working on a quick survey for a company who will be getting about 200k (at peak) visitors hourly for about 2 days straight. I was just wondering if using $_SESSION variables would tie up the server. All that we are storing in those variables are at most a 6 character string or a single digit integer. I'm new to the PHP world so I'm not sure how reliable or how much $_Session variables will tie up the servers. The servers we are using will be cloud servers.
One final note is that the the sessions will only last maybe 6 - 10 minutes tops for each visitor before I close it out.
Any help will be greatly appreciated!
By default, data in $_SESSION will be written to disk upon each call to session_write_close(), or upon script termination. There is no way to know for sure how this will perform without testing the final application on the server hardware you will be using. Since the volume of data is small, the real worry is disk latency. An easy workaround for this would be to set PHP's session_save_path to an in-memory filesystem.
Tie up how? Disk space? Storing a simple 6char string using the default file-based session handler will take up about 6+length-of-variable-name + ~6 chars of space on the disk. There'll be some overhead to load/unserialize the data in the session file. but it'll be much less than the initial overhead of loading/compiling the script that's using the session data.
Remember, PHP's default sessions use the disk as their storage media - they're not persisted in memory after the script exits.
I think you don't want to store data in sessions, because it writes to disk. If someone hits the app with multiple requests, are you able to guarantee that they hit the same machine in the cloud? That's rather complicated to write. I would cookie the user instead.
http://php.about.com/od/learnphp/qt/session_cookie.htm
http://www.quora.com/Does-PHP-handle-sessions-by-writing-session-variable-data-to-disc-or-does-this-information-persist-only-in-RAM-Will-accessing-session-data-cause-a-disc-read-in-PHP
Like the others said, I'd use Memcached if you want to scale, but to answer your question directly, I think your server should be able to handle the usage you describe.
In PHP you can change the session handler. The default session handler is to write data in a temp file, with one file per session. It works okay, but has limitations when runnning high traffic apps (although with 200K/hour you shoudln't have problems with the default handler).
And easy solution is to use the session handler for Memcached, with the PECL/Memcache extension (not to confuse with the PECL/Memcached extension):
http://www.php.net/manual/en/memcache.examples-overview.php (see example #2)

Is there a variable scope that is accessible anywhere in PHP?

I'd like to create something like a very basic chat application. I don't want to use a database, since it'd cause a heavy load on an already strained db. I also don't want to use a flat file, because it have a feeling that it'd become a mess or that it'll have lots of read/writes...
So, I'm wondering if there is a way to have a variable that is accessible in any file and at any time.
Well if you don't want a file, you're left with shared memory.
You could try PHP's shared memory functions, or use an extension like memcache or APC.
You can't share variable values among separate requests - think of each request like the entire program is starting and finishing each time, even if there are several requests happening at once.
You could look into storing data in a cache layer (for example, memcached) however it sounds like you need to cache your database if it's under heavy load. I'd recommend caching your database (again memcached or file-based storage; serialize() data first) and then when that problem is solved store the chat data in the database (which is in turn cached). You need to store it persistently somewhere.
There isn't such thing. Try creating a basic file that saves serialized/json'd version of the variable you want, use php's flock to manage access to that file, cycle the file every hour/day. Since it's no big traffic simple app, I think this will be okay.

Categories