Sunday, February 1, 2015

GEOIP pear pecl PHP extension for location IP based conversion to city country, longitude, latitude

  1. Download .dat.gz databases from maxmind: http://geolite.maxmind.com/download/geoip/database/
  2. Install geoip via yum.
    yum install GeoIP GeoIP-devel
  3. You also might want to download database with ip addresses from Maxmind website and place it in /usr/share/GeoIP (which is a default location of geoip upon installation).
  4. Install PECL extension
    pecl install geoip
  5. Add extension=geoip.so to your /etc/php.ini
  6. Restart apache /etc/init.d/httpd restart

For Ubuntu:

apt-get install libgeoip-dev libgeoip1
apt-get install php5-geoip

then you need to copy GeoLiteCity.dat.gz to /usr/share/GeoIP/ and extract it and rename it to GeoIPCity.dat
then restart your web server:

service apache2 restart

Check if PHP session already started? session_start check

Simplest way to check if PHP session has already started or not


<?php
  if (!isset ($_COOKIE[ini_get('session.name')])) {
    session_start();
  }
?>

Check if PHP script was executed from command line CLI or not

Simple and fool proof PHP code snippet to detect if the current running script was executed from command line (CLI) or not (most likely browser).



if(is_null($argc)) {
    //NOT CLI
} else {
    //FROM CLI
}

Check if another instance / process (by PID) of PHP script running / executed already exists via temporary file lock

If you are trying to make sure your back-end running script will only have a single instance running, you may want to use a script like this.


// ---- SOMEWHERE AT THE TOP OF YOUR SCRIPT -----------
// TRY TO GET EXCLUSIVE LOCK

$fp_pid_pathfilename = "/tmp/your_script_name.php.lock";

$fp_pid_lock = fopen($fp_pid_pathfilename, "w");

// try to get exclusive lock, non-blocking
if (!flock($fp_pid_lock, LOCK_EX|LOCK_NB)) {
	// failed to get lock
	die("Another instance is already running.\n");
} else {
	// got lock, write PID
	fwrite($fp_pid_lock, getmypid());
}

.
.
.


// ---- THEN AT THE END OF THE SCRIPT ------------
// CLOSE OR RELEASE PROCESS PID LOCK

fclose($fp_pid_lock);
unlink($fp_pid_pathfilename);


TIP: Please make sure you store your lock file in /tmp, the reason is simple, most linux server will remove all files/directory for /tmp directory, therefore if you have a sudden power failure, your lock file will not be stuck.

My personal list of HTTP codes along with usage for PHP

Here are my personal list of HTTP codes I frequently used with PHP:



header('HTTP/1.1 200 OK');
 
// Page was not found:
header('HTTP/1.1 404 Not Found');
 
// Access forbidden:
header('HTTP/1.1 403 Forbidden');
 
// The page moved permanently should be used for
// all redrictions, because search engines know
// what's going on and can easily update their urls.
header('HTTP/1.1 301 Moved Permanently');
 
// Server error
header('HTTP/1.1 500 Internal Server Error');
 
// Redirect to a new location:
header('Location: http://www.example.org/');
 
// Redriect with a delay:
header('Refresh: 10; url=http://www.example.org/');
print 'You will be redirected in 10 seconds';
 
// override X-Powered-By value
header('X-Powered-By: PHP/4.4.0');
header('X-Powered-By: Brain/0.6b');
 
// content language (en = English)
header('Content-language: en');
 
// last modified (good for caching)
$time = time() - 60; // or filemtime($fn), etc
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $time).' GMT');
 
// header for telling the browser that the content
// did not get changed
header('HTTP/1.1 304 Not Modified');
 
// set content length (good for caching):
header('Content-Length: 1234');
 
// Headers for an download:
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="example.zip"'); 
header('Content-Transfer-Encoding: binary');
// load the file to send:
readfile('example.zip');
 
// Disable caching of the current document
header('Cache-Control: no-cache, no-store, max-age=0, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Pragma: no-cache');
 
// set content type
header('Content-Type: text/html; charset=iso-8859-1');
header('Content-Type: text/html; charset=utf-8');
header('Content-Type: text/plain'); // plain text file
header('Content-Type: image/jpeg'); // JPG picture
header('Content-Type: application/zip'); // ZIP file
header('Content-Type: application/pdf'); // PDF file
header('Content-Type: audio/mpeg'); // Audio MPEG (MP3,...) file
header('Content-Type: application/x-shockwave-flash'); // Flash animation
 
// force basic HTTP authentication
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Basic realm="Top Secret"');
print 'Text that will be displayed if the user hits cancel or ';
print 'enters wrong login data';

PHP array sort ascending using closure function usort sorting

Any PHP developer who has used usort() or uasort() function before PHP support closure know it is a pain in the rear.  Having to declare a callback function just liters your code.  I have been doing this code which I found to be the simplest and most elegant:

<?php
usort($input_array, function(){
	if($a['something'] == $b['something']) return 0;
	return ($b < $a ? -1 : 1);
});
?>

Converting SimpleXMLElement returned object to associative PHP array

This trick is pretty cool, putting SimpleXMLElement output through json encode and decode actually yield a perfect PHP associative array. Nice!


<?php
$xml = '<blah>123</blah>';

$simpleXML_obj = new SimpleXMLElement($xml);
// echo __LINE__.':simpleXML_obj: '.print_r($simpleXML_obj, true)."\n";

if(!empty($simpleXML_obj)){
	$json = json_encode($simpleXML_obj);
	if(!empty($json)){
		$arr = json_decode($json, true);
		if(!empty($arr)){
			// Got nice associative array!
			echo __LINE__.':arr: '.print_r($arr, true)."\n";
		}
	}
}
?>

Output image file content using PHP with correct header for cache control (using etag and last-modified)

Creating code to read and output image content using PHP is easy. However it takes a little bit more PHP-fu to make your code to communicate with browser so cache can be used effectively.

What do I mean by that?  we will generate additional headers like:

Cache-control: public
Last-Modified:  ....
Etag:  ....


and we will check if browser provide us with HTTP_IF_MODIFIED_SINCE and HTTP_IF_NONE_MATCH to be compared against current file content to check if file_content have changed.

If the current file content is the same we will delivery

HTTP/1.1 304 Not Modified

if content is NOT the same, we will deliver the actual content of the file.

Here is the my code snippet to accomplish this:



Enjoy!