Caching variables in PHP - php

I've been caching the output buffer of pages lately, but now I want to cache the values of variables.
I have a PHP file that does a bunch of MySQL queries, then fills variables with various data from those queries.
Some of those variables will never change but some will change quite often. How can I cache certain variables in this manner? I'm using file-based caching, if it helps.

Yup, file based caching is an option.
There are also other options like memcache and APC
You should have a look at these as well. If your application is putting a lot of load on your MySQL server, and if your DB is already optimized, caching is a step you can take.

You can dump any variable (including an array) using serialize, and the inverse is unserialize.
Dumping to a file would be quite a useless cache solution, you can consider using memcache which can store any variable in memory, but requires some work on server side.
I find that a local mysql with MEMORY tables can be useful, too...

I dont know, how you structured your current caching stuff, so this is just a short template on how you can save any kind of variable (as long as its content is serializeable) to a file.
file_put_contents($filename, serialize($variable));

Since you asked about file-based caching, both memcache and APC are no option, although I would certainly recommend both in cases where the stored data is not too large.
For file based caching, I would recommend you to use a caching framework. For example, you could use Zend_Cache from the Zend Framework. It allows you to store your query results in files by using a nice object oriented interface. Plus, you've got a lot of options, such as validation and serialization. There are also other caching frameworks out there.

Related

Should I store application-scope variable inside a file in PHP?

I want store a variable shared between sessions (application-scope):
It is not user session-specific (so I can't put it in $_SESSION[]).
It is a long term storage (so I can't use APC - Alternative PHP Cache).
So, I use a file do store the variable and access it using file_get_contents and file_put_contents functions.
Is it a good way of proceeding or is there any alternative?
It's clear your's is a global, server side issue. I would use a Database to do it. Just CRUD when needed.
You'rs may do the work, but I recommend the database approach, due to the enhanced capabilities that it provides like logging, checking the history of events. I think is a cleaner solution.

How does php opcode cache (apc) work with session-specific variables?

Looking at creating my first web application using php and an opcode cache.
I vaguely understand why it's beneficial in theory.
However, in practice - how does apc work with opcodes compiled from session specific variables? If one page (say somesharedpage.php) is cached, how are variables within (that may be different for every user) treated and handled?
Simply, APC works with code and not data, because data doesn't contain any opcodes.
When should data be added to apc?
Data that you would want to cache using apc_fetch(), apd_store() etc. are ideally values that would take some processing time to get generated, rather than simply "all my globals".

Optimized way to read settings from database only once in PHP

I'm working on a big project with several http servers that use one main sql database.
The project has many settings that are frequently used(almost every request).
The settings are stored in the main sql database.
I wanted to know, if there is some way to initialize settings only once in php, because it makes no sense for every request to go and read same setting from sql server over and over again, it feels like a waste of resources.
Thanks in advance
2 solutions:
Create a (perhaps also PHP) script that exports settings from database into a plain text file, and includes that file on every http server;
use a memory cache server like http://memcached.org/ and preload data there from an external script, then have http servers connect to memcache instead of SQL.
Edit: Other than that, PHP does not give you a real web application, where you "run" your application and it has its own memory and persistant, global variables. This is one of the reasons I personally got tired of PHP and moved to Python (and Django, specifically).
Hard code these settings in your PHP code.
// Your current code, somthing like this:
$setting_1 = getDataFromMySQL('setting1');
// Hard coded
$setting_1 = TRUE;
You can use shared memory in php if it is compiled that way.
Another possibility is that you store a combined value of your settings as PHP code in one field (a PHP array for example), then you can read them all with only one query to the DB server. Of course this cached value have to be updated when settings change.
APC is the best solution if you are using a single server, otherwise I would go with memcached. However, you may also consider a MYSQL memory table, it is very efficient for fast reads and writes. Another solution is using Linux to keep and call settings with Linux exec. However, this might be a trouble and there might be some security issues. Also let me remind you that efficient INNODB indexes can help you a lot. MYISAM is also considered a good "read" performer, however my benchmarks show me that INNODB indexes are faster.
You can store the settings in the user's session -
session_start();
if (!isset($_SESSION['settings'])) {
$settings_array = //pulled from database
$_SESSION['settings'] = $settings_array;
}
That way, it'll only query once per user
You could use a session to store those settings.

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.

Using memcached as a session storage with CodeIgniter

I am researching possibilities of using memcached as a session storage for a system built on CodeIgniter. Has anybody done this before(that's probably a stupid question :) and if so what's your experience folks? Have you used any existing libraries/extensions?
As far as performance improvement what have you seen? Any caveats?
Having PHP put the sessions into Memcache directly, rather than through framework code is easy - it's just changing two lines in the PHP.ini:
# see http://php.net/manual/en/memcache.ini.php
session.save_handler = memcache
session.save_path="tcp://127.0.0.1:11211?persistent=1&weight=1&timeout=1&retry_interval=15"
This uses the slightly older (but still entirely supported) 'memcache' extension from PECL.
You can choose the CodeIgniter Multicache Library, which can be found here: http://www.haughin.com/code/multicache/
In the code you can simple use like this:
$this->load->library('cache');
//To use memcache
$this->cache->useMemcache($iptomemcache, $port); /*if you want, you can check to see if the connection even worked, as this will return false if the connection failed.*/
$this->cache->save('testkey', 'testdata', NULL, 3600); /*caches the testdata string for 1 hour. */
echo $this->cache->get('testkey');
//To switch back to file based caching
$this->cache->useFile();
//etc.
It's not practical to use Memcached for storage of relational data (like MySQL); it would be inefficient to request each item from Memcached and then test to see if it matches a query. There are better solutions to a problem like that (consider Memory tables in MySQL, for instance).
On the other hand, if you're looking for simple key/value storage, that's certainly a practical application for Memcached. What I'd be a little wary of, though, is writing a CodeIgniter driver for it. The interface for Memcached in PHP is already dead simple:
$memcached->get('my key');
$memcached->set('my key', 'my value');
I would suggest simply using the Memcached classes directly. Adding all the extra overhead to CI just seems dirty and unnecessary to me.
On the flip-side of that, I've seen implementations of Memcached used for CodeIgniter's session engine. That's certainly a very valid reason to write a driver, and I would highly encourage it (sessions are a pain in the neck to scale).
Good luck

Categories