Hold PHP variables RAM or making variables available to the application as a whole?

Hi Sitepointer,

I have written a website template system for multilingual websites. It’s fairly simple.

There are 3 database tables, placeholder, placeholder_language and language (see structure below).

In my template I replace a word in squared brackets [example] with what ever that word is in the users selected language.

using str_replace I replace the bracketed word [example] for ‘example’ if the user is viewing the site in English and ‘ejemplo’ if the user is viewing the site in Spanish.

The placeholders are parsed is done on every page load. My worry is that this will cause excessive load with multiple users.

Since these variables don’t change is there a way of holding them in RAM or making them available as variables to the application as a whole?

Many thanks. Muchas Gracias.

Tables follow.

CREATE TABLE IF NOT EXISTS placeholder (
placeholder_id int(11) NOT NULL AUTO_INCREMENT,
placeholder_name varchar(255) NOT NULL,
PRIMARY KEY (placeholder_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0;

CREATE TABLE IF NOT EXISTS placeholder_language (
placeholder_language_id int(11) NOT NULL AUTO_INCREMENT,
placeholder_id int(11) NOT NULL,
language_id int(11) NOT NULL,
placeholder_language_name varchar(255) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (placeholder_language_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;

CREATE TABLE IF NOT EXISTS language (
language_id int(11) NOT NULL AUTO_INCREMENT,
language_name varchar(255) NOT NULL
PRIMARY KEY (language_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;

have you thought about storing them in $_SESSION ?

Yup, +1. If you want them in memory, a properly indexed table / query is really the only way to go.

MySQL and most other DB engines have memcaches for the results of the most frequently ran queries, so without even touching the PHP code you can increase caching of the results by increasing the db engines’ cache size. Within PHP itself there is APC and memcache. A final trick is to mount a RAM disk on your server and have PHP write to a file on that ram disk.

This is the function I use to replace the placeholders.

function  replace_placeholders($output){
	//replace placeholders
	if (!empty($_GET['language_id'])) {
	$_SESSION['language_id'] = $_GET['language_id'];
	}
	if (isset($_SESSION['language_id'])) {
	$language_id = $_SESSION['language_id'];
	}
	else {
	$language_id = '1';
	}
	$query = "SELECT placeholder_name, placeholder_language_name FROM placeholder, placeholder_language
	WHERE placeholder.placeholder_id = placeholder_language.placeholder_id
	AND language_id = '$language_id'";
	
	$result = mysql_query($query);
	
	$pln_array = array();
	$pn_array = array();
	
	while ($array = mysql_fetch_assoc($result)) {
		$placeholder_name = $array['placeholder_name'];
		$placeholder_language_name = ucfirst($array['placeholder_language_name']);
		
		array_push($pln_array,$placeholder_language_name);
		array_push($pn_array,$placeholder_name);
		}
		$output = str_replace($pn_array,$pln_array,$output);
	return $output;
}

I would go this route as well. You can also manually store via APC and memcached as well. APC does a pretty good job of automatic caching with minimal configuration.

The problem with application scoping and PHP is that one cannot tell is a given session is the first or last, in order to facilitate proper cleanup. While you can write a counter to file, you probably shouldn’t. Also, keep in mind the following things:

  1. Memory is not share between machines, therefore, a later move to a cluster could potentially cause problems.
  2. Users of different sessions may have selected different languages/locales, and sharing this across all sessions would pose problems.

I post this information as further support for the db solution.

What I would do, however, is group certain phrases into phrasegroups in order to facilitate seletion of only the conversions you’ll need. E.G. put all common phrases in a group, all phrases used on the login screen in a group.