I have a cluster of PHP hosts serving a small PHP script. The script retrieves an array of key/value pairs from the database at the beginning of the script, that are configuration values.
I would like to avoid the retrieving of these configuration data from the database for every request, in order to optimize.
My idea was that the script loads the data from the database only for the first request and it stores these variables into some kind of shared memory that is persistent among all sessions.
I've tried to use PHP global variables but they are all destroyed at the end of the script...
Also, I would like to avoid using a config file because as I said I have more than one host serving the script and I'd like to store the data centralized.
When I need to store small bits of data across scripts, I usually use apc
apc_add('config', array('a' => 'b'));
$config = apc_fetch('config');
...among sessions
rather implies that you are already using sessions - so why not just use a custom session handler?
You load the session data using the session id, and overload the config. Optionally you could set it up so you can call the read method and only return the config data without searching for conventional session data.
Probably the most efficient way to do this would be to run a daemon - that way you can keep the config data in PHP variables. There's a nice single threaded server implementation here.
You can keep this as:-
$_SESSION['_config_data']['index_1'] = 'value_1';
$_SESSION['_config_data']['index_2'] = 'value_2';
$_SESSION['_config_data']['index_3'] = 'value_3';
...
In this way, you will get all the configuration data stored in the session variable "$_SESSION['_config_data']".
But you need to check at the starting of the setting method, whether the session variable "$_SESSION['_config_data']" exists with some pre-filled data or not. If it is, then you don't need to set the configuration data for each page request.
Hope it helps.
Answer is memcached: http://memcached.org/
Its a sort thing that was meant to for this kind of scenarios and there are alot of good tutorials but official php documentation is a good starting point: http://php.net/manual/en/book.memcache.php
Related
I'm writing a web application in PHP and I want to declare an array, in which i want to save the host and how often this host has opened my web application. I want to add the variable to something like the application scope in JSP. I've tried to add this array to $_SERVER, but this hasn't worked. If I try to acess the variable in another file with $_SERVER[$_GET["id"]] the variable is always NULL. Can someone please help me?
Here my code:
if(empty($_SERVER[$_GET["id"]])){
$_SERVER[$_GET["id"]]=array($country, 1);
}else{
$_SERVER[$_GET["id"]][$country]+=1;
}
several things:
$_SERVER is for SERVER do not use it to play global array.
$_SESSION is returning null because you probably didn't declare any
session_start at the beginning of your file. If you don't do that, the session cookies (variables) are not shared and this is why its null.
this is the basic of vanilla php.
From here, you could explore a micro framework that has this built in...
UPDATE
due to your misconception of "session", what you want to do is to persist data. If you want to "share" this array of yours among different users (aka data sharing among session), I would recommend to persist via data storage:
sqlite/memory or sqlite/file
redis (value/key and its quick)
mysql or any sql/no-sql
least favorable IMO: write to a simple file and retrieve. The only issue with this, is that you will have "lock" condition but then again so will the other ones
Every time a page is loaded I connect to the database to fetch the settings table where the basic application settings are stored. It looks uneficcient. I have an idea to temporary store the $settings array in $_SESSION variable. So every time the script is started it checks if $_SESSION['settings'] is empty and loads the data from DB only if it is.
My questions are:
1)Is this normal practice or there are serious pitfalls?
2)Will this speed up my application?
It looks unefficient.
it looks or it IS inefficient?
I have an idea to temporary store the $settings array in $_SESSION variable.
That's wrong idea. Sessions are for personal data, not site-wide settings. If you want to read your settings from a file - include it!
Will this speed up my application?
Is anything wrong with your application speed at the moment?
I would guess performance benefits of this would be negligible at best, and potentially harmful at worst.
Either way $_SESSION isn't really intended to be used this way, it's for data relating to a specific user, and as a general rule I try to keep it as concise as possible.
A better solution you might consider is caching the settings locally as a PHP file, it's not too hard to script something up to generate a file that creates a simple key => value array from the database that you can include. e.g.
<?php
// myconfig.php
return array(
'mysetting' => 'value',
);
Then you can just include this file to get your config values:
<?php
// app.php
$config = include('myconfig.php');
echo $config['mysetting']; // 'value'
I would not recommend using PHP's $_SESSION as a local cache. For each visitor that comes to your site, you'll need to populate that $_SESSION variable. This is inefficient, since each visitor will get a session when they don't need. It's also difficult to manage, since changes to your settings data won't immediately be populated into the $_SESSION variable. I'd recommend something like memcached or even apc local object cache for this.
What's the best way to store temp data in PHP across page views? MySQL or server side cookies? Or something else I don't know about?
You could use the $_SESSION variable. I've seen people using it to keep session information such as cart contents, and generally to pass information from one page to another.
There's an extensive documentation on session variables at http://www.php.net/manual/en/ref.session.php .
I would advise against MySql in this case.
I prefer using PHP session for storing data on server side. For efficiency you can use memcached to save session values (default are saved on filesystem).
You can use $_SESSION like Clement suggested, but $_COOKIE may be appropriate also. Especially if you need to fetch the values client side. Here are some examples on how to use Cookies in PHP: http://www.w3schools.com/php/php_cookies.asp
Session variable is backed by a storage mechanism, that is, when the request finishes the session gets written by the session handler, by default this is to a file. On the next request it is pulled back from that file (or whatever else the session handler uses).
If you're reading and writing this data on every request, just stick with a the $_SESSION variables, the overhead of connecting, querying and updating a database will not be faster than the default $_SESSION.
You'll probably only ever want to use a database backed session if you are running multiple load-balanced servers and need to share the session data between them. In this case, if you find the overhead of the database sessions to be slowing down your site to a noticeable degree you might consider sticking memcached between your web server and the database.
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!
Does PHP have global variables that can be modified by one running script and read by another?
No, by design PHP is a "share nothing" architecture, which means nothing is shared between processes running at the same time or between requests running one after another. There are ways to share data, but you have to do it explicitly.
If you just want to share between 2 requests from the same user, sessions or cookies might be the way to go.
If you want to share between multiple users, you probably want some sort of shared persistence, either short term in a cache (eg. memcached) or more robust like a database.
Either way, the data is actually being retrieved and reconstructed on each request. It's just handled automatically for you in the case of sessions.
You can actually do this using shared memory, or APC (which is using shared memory itself).
You can use $_SESSION, i.e.:
script1.php
<?php
session_start();
$_SESSION['myVar'] = "something";
?>
script2.php
<?php
session_start();
echo $_SESSION['myVar'];
//something
?>
The only one which could be accessed between scripts is the superglobal $_SESSION array. This is because whatever you store in the array is sent to a cookie, which can then be picked up by the next PHP script.
Global variables simply mean that they can be accessed in the script regardless of the scope; that doesn't mean they can be sent between scripts.
So either you have to transfer the variables using the $_SESSION array (this stores a cookie on the client computer, so don't sent any sensitive information through that array) or you can either POST or GET between the scripts to send the variables.
Each request is handled by a php instance of its own. Global variables in php are only accessible from within the same php instance. However you can use something like the memchached module to share data between different instances (which should usually be faster than writing the data to the filesystem).
Not as such, but you can use cookies or sessions to maintain data for duration of a user's browsing experience, or you can write to a database or file on-disk if the information needs to persist beyond that.
Another common substitution for global variables in PHP is the shared use of a database like MySQL (albeit not a perfect one)
Global variables are bad in most programming. They're especially bad in multithreaded/multiuser systems like webapps. Avoid. If you must use global variables (rather than global constants) put them in a database with transactions guarding updates.
Since you talk about different scripts though, it sounds like what you really want is a web application framework in a more application oriented language --- something like Django (python) or Rails (ruby). These let you think of your code much more like a cohesive PROGRAM, rather than a lot of loosely connected scripts that process web requests.
I made a tiny library (~2 KB; <100 lines) that allows you to do just this: varDx
It has functions to write, read, modify, check and delete data.
It implements serialization, and therefore supports all data types.
Here's how you can use it:
<?php
require 'varDx.php';
$dx = new \varDx\cDX; //create an object
$dx->def('file.dat'); //define data file
$val1 = "this is a string";
$dx->write('data1', $val1); //writes key to file
echo $dx->read('data1'); //returns key value from file