Application semaphores using MySQL
Many tasks require some application part to run in one instance per time, such as mail delivery cron job. And each time developers should invent some mechanism to determine if another copy is running. Usually no of these mechanisms are 100% reliable.
The solution is already found by MySQL development team. It is "named locks".
Application can try to acquire a named lock on its start and check if another copy is running.
How can it be implemented:
$res = mysql_query("SELECT GET_LOCK('lockname', 2)");
$result = mysql_fetch_array($res);
if (!intval($result[0])) {
echo "Cannot run until previous instance finish!";
exit;
}
// Do anything we need
mysql_query("SELECT RELEASE_LOCK('lockname')");
What we get using this mechanism:
- GET_LOCK will fail if a lock with specified name already set and script can stop;
- Script can work as long time as it needs;
- RELEASE_LOCK will free acquired lock and script will run successfully next time;
- If the script will fail with fatal error, time restriction or somehow else, MySQL will free its lock automatically on connection close;
- No additional files, table records, no stupid checks. Everything is done in 2 queries;
- We can be 100% sure another copy is running now, no lost locks;
Note: All the above is true if you use only one lock per script (and probably without persistent connection) because callng GET_LOCK second time during the same session will release previous lock. This feature is very usefull for cronjobs.
To read more about these functions - visit MySQL Manual
PHP DOMDocument class and HTML entities
DOMDocument class behaves strange sometimes. It could omit some entities like “ and some valid UTF-8 characters (it also may do so for other encodings). This probably could be fixed by using own DTD, but there is a simple way too. Each HTML entity has its binary code, so DOMDocument will export your entities correctly if you replace the entities by the appropriate codes. I have a small list of them. By using the following function you can avoid symbols loss:
function parseEntities($string) {
$entities = array (
"auml" => "ä",
"ouml" => "ö",
"uuml" => "ü",
"szlig" => "ß",
"Auml" => "Ä",
"Ouml" => "Ö",
"Uuml" => "Ü",
"nbsp" => " ",
"Agrave" => "À",
"Egrave" => "È",
"Eacute" => "É",
"Ecirc" => "Ê",
"egrave" => "è",
"eacute" => "é",
"ecirc" => "ê",
"agrave" => "à",
"iuml" => "ï",
"ugrave" => "ù",
"ucirc" => "û",
"uuml" => "ü",
"ccedil" => "ç",
"AElig" => "Æ",
"aelig" => "Ŋ",
"OElig" => "Œ",
"oelig" => "œ",
"angst" => "Å",
"cent" => "¢",
"copy" => "©",
"Dagger" => "‡",
"dagger" => "†",
"deg" => "°",
"emsp" => " ",
"ensp" => " ",
"ETH" => "Ð",
"eth" => "ð",
"euro" => "€",
"half" => "½",
"laquo" => "«",
"ldquo" => "“",
"lsquo" => "‘",
"mdash" => "—",
"micro" => "µ",
"middot" => "·",
"ndash" => "–",
"not" => "¬",
"numsp" => " ",
"para" => "¶",
"permil" => "‰",
"puncsp" => " ",
"raquo" => "»",
"rdquo" => "”",
"rsquo" => "’",
"reg" => "®",
"sect" => "§",
"THORN" => "Þ",
"thorn" => "þ",
"trade" => "™"
);
foreach ($entities as $ent=>$repl) {
$string = preg_replace('/&'.$ent.';?/m', $repl, $string);
}
return $string;
}
This list contains not all the entities, but it is easy to inroduce new ones without any other code influence.
array_merge_recursive problem in PHP 5.2.5
I faced a problem with Plugin Everywhere project some time ago. During the deep debugging I found that the code doesn't have any problem, but PHP had.
PHP 5.2.5 has a problem with array_merge_recursive function. It was grouping NULL values into the one. I even found this bug here. Plugin Manager uses that function for queues bulding, so this caused handlers call problem.
It's just the interesting fact, so be careful