I read a lot about how evil global variables are in PHP, but I am trying to optimize a code I am writing. In this webapp a lot of functions are using the same data (about up to 50 items at once) to perform numerous operations and the data itself is stored in a database.
I have two options which are a) fetching data from the database EVERY TIME a function needs it or b) fetching the data ONCE and storing it in (a) global variable(s).
When it comes to performance, which option is the best ?
There is nothing wrong with "global variables". It is passing data into functions using global keyword is prohibited (but nevertheless, using this keyword to pass indeed global variable is okay).
Yes, speaking of one script instance (and sane amount of data), there is no use for reaching for database for the same data again. Fetch it once and then use in whatever functions you need. It's okay and nothing wrong with it.
When it comes to performance, here comes the best option ever:
do care of performance only if you have a certain reason to.
Related
I´m creating a new website and in the webs I´ve coded before I always have been using a php file to store permanent that is used a lot that is called with an include from the index.php.
The purpose of that is to avoid doing extra queries as this data is used every time and doesn´t change, but now I´ve concerns if that is a good practice.
One example of that is the different languages options that the website has, that is shown everytime and I don´t want to do an extra query every time.
Is that a good practise or it´s better to store everything on the DB and make more queries?
I store my language dependent strings in separate files, grouped by function, for example email. So I would have a template called
lng_email
Then I add a suffix to it in the include statement. For English the example would be
lng_email_en.php
The suffix is fetched at login and stored in the session variable.
Well after 3 years since I posted the question, I end up storing the data the following way:
Almost all the data is stored in the mysql database, where it's easy to manage.
I use the $_SESSION var only for user's data that is being called and used during the user's session only.
I have a php file where I store general data that's being use a lot by the code and won't be changed in the short or mid term. This way I save the code to do several queries to the database. I store them within a function so they can be retrieved by other function and avoiding to declare them as a global. As an example:
function retrieve_privacy_list(){
$privacy_list = array(
1=>'public',
2=>'reduced',
3=>'private');
return $privacy_list;
}
For large arrays, is it better to save the data to global variables or query the database each time I need them? In my situation keeping them local scope and passing them to functions isn't an option.
I'm using wordpress and in most pages I get every user and all metadata attached to them. Often times I use these variables in multiple places on the same page. Unfortunately wordpress won't let me pass variables between templates so I'm stuck either using global variables or calling the database each time. Eventually, this will be hundreds of users with a lot of metadata attached to each. Should I call the database each time to keep the variables local, or should save them to global variables to save on database queries? What are the considerations? Should I worry about performance, overhead, and/or other issues?
Thanks so much!
The only real solution to your problem is using some kind of cache system (Memcache and Redis are your best options). Fortunately, there are plenty of Wordpress plugins that make the integration an easy thing. For instance:
Redis: https://wordpress.org/plugins/redis-object-cache/
Memcache: https://wordpress.org/plugins/memcached/
EDIT
If you only want to cache a few databases calls, you can forget about Wordpress plugins and start coding a bit. Let's say you only want to cache the call for retrieving the list of users from database, and let's assume you are using Memcache to accomplish this task (Memcache stores key-value pairs and allows super fast access to a value given a key).
Query Memcache asking for the key "users".
Memcache still doesn't have such key, so you'll have a cache fail and after it, you'll query your database to retrieve the user list. Now serialize the database response (serialize and json_encode are two different ways to do this) and store the key "users" along this serialized value in your memcache.
Next time you query your memcache asking for "users", you'll get a hit. In this moment you just have to unserialize the value and work with your user list.
And that's all. Now you just have to decide what you want to cache and apply this procedure to those elements.
You shouldn't have to perform the calls but once per page, you might have to execute the call once for every page. So I would suggest you creating some sort of class to interact with your database that you can call on to get the data that you need. I would also recommend using stored procedures and functions on your database instead of straight queries since this will help both with security and separation of application logic and data functionality.
A general PHP question about organizing a website: for efficiency purposes, is it better to store data from MySQL queries into global arrays, or to make a new query every time data is needed? I am thinking specifically of a sports stats-oriented website, with a lot of data that does not necessarily change very often.
I have heard that storing the data into arrays is much more efficient, but I don't see how since global variables are only global in the scope of the current PHP page. Ideally, I'd like to populate all my arrays once I start my server. Should I use session variables then? I haven't heard of anybody doing that.
Session variable won't resolve the issue, as the session is not global as well (unless you hack it by setting the same session_id to all visitors).
If you have a lot of traffic and you need to save queries, than use a cache server like memcached or redis.
If you can't install memcached or redis, you can create a PHP file that contains the arrays, and include it in the scripts - e.g. use file caching. The bad thing about this approach is that you will use a lot of memory - the whole data should be read in the memory by any PHP script, by any visitor. So in case the database is not the bottleneck, better keep the queries.
I am working on a project that is being built with a standard LAMP stack. Currently, I merely output the results of the query onto the page - the results are not being stored in objects at all.
In the future, I would like to edit the results of the query. I imagine that this would much easier if the results were stored in PHP objects.
Would it be more beneficial to store the objects themselves in a DB (via serialization/deserialization), or to create the objects when need be (after executing the query) and then destroying them when they are no longer needed?
You'd be better off storing a copy of the results directly in your object, rather than a serialized result handle. Serializing the result handle will NOT preserve locks, server-side variables, table state, transactions, or the data in the result set. MySQL has no provision for storing a connection handle in this fashion, so it'd be seen as a regular disconnect and resulting in outstanding queries being cleaned up, variables destroyed, transactions rolled back (or committed), etc...
As well, the data retrieved by the query is not actually fetched across the connection until you do a fetch_row()-type call, so you'd not even have that in your serialized handle.
Always create the objects in php, and destroy them later. In order to serialize you will need to use longtext or like field, which are known to be slow and you cannot index on them. If you are always doing a Select All, then go ahead, but if you ever use conditions or advanced queries, you should have all data separated.
It depends on many factors. If you are running the exact same queries again and again, then yes, store the results in your database. But why serialise them? If you tried Object-relational mapping, you could have a much easier to maintain query object, that you could store in a well organised relational database.
If you are not running the same queries very often, I would recommend caching the output in another way.
Would it be more beneficial to store the objects themselves in a DB (via serialization/deserialization), or to create the objects when need be (after executing the query) and then destroying them when they are no longer needed?
No. Somebody somewhere has done this for you. What would be beneficial is for you to use an existing ORM. It doesn't matter which one, just pick one and use it. You'll be lightyears ahead and get your project out the in a fraction of the time.
You should use a PHP framework while you're at it, many of which come coupled to an ORM.
I want to add some static information associated with string keys to all of my pages. The individual PHP pages use some of that information filtered by a query string. Which is the better approach to add this information? Generate a 100K (or larger if more info is needed later) PHP file with an associated array or add an other DB table with this info and query that?
The first solution involves loading the 100K file every time even if I use only some of the information on the current page. The second on the other hand adds an extra database call to the rendering of every page.
Which is the less costly if there are a large number of pages? Loading a PHP file or making an extra db call?
Unless it is shown to really be a bottleneck (be it including the php file or querying the database), you should choose the option that is best maintainable.
My guess is that it is the second option. Store it in a database.
Storing it in a database is a much better plan. With the database you can provide better data constraints, more easily cross reference with other data and create strong relationships. You may or may not need that at this time, but it's a much more flexible solution in the end.
What is the data used for? I'm wondering if the data you need could be stored in a session variable/cookie once it is pulled from the database which would allow you to not query the db on the rendering of every page.
If you were to leverage a PHP file then utilizing APC or some other opcode cache will mitigate performance concerns as your PHP files will only be loaded each time the file changes.
However, as others have noted, a database is the best place to store this stuff as it is much easier to maintain (this should be your priority to begin with).
Having ensured ease of maintenance and a working application, should you require a performance boost then generally accepted practice would be to cache this static data in an in-memory key/value store such as memcached. This will give you rapid access to your static values (for most requests).
I wouldn't call this information "static".
To me, it's just a routine call to get dome information from the database, among other calls being made to assemble whole page. What I am missing?
And I do agree with Dennis, all optimizations should be based on real needs and profiling. Otherwise it's effect could be opposite.
If you want to utilize some caching, consider to implement Conditional GET for the whole page.