10 useful PHP PEAR packages

MDB2

PEAR MDB2 is a merge of the PEAR DB and Metabase php database abstraction layers.

It provides a common API for all supported RDBMS. The main difference to most
other DB abstraction packages is that MDB2 goes much further to ensure
portability. MDB2 provides most of its many features optionally that
can be used to construct portable SQL statements:

  • Object-Oriented API
  • A DSN (data source name) or array format for specifying database servers
  • Datatype abstraction and on demand datatype conversion
  • Various optional fetch modes to fix portability issues
  • Portable error codes
  • Sequential and non sequential row fetching as well as bulk fetching
  • Ability to make buffered and unbuffered queries
  • Ordered array and associative array for the fetched rows
  • Prepare/execute (bind) named and unnamed placeholder emulation
  • Sequence/autoincrement emulation
  • Replace emulation
  • Limited sub select emulation
  • Row limit emulation
  • Transactions/savepoint support
  • Large Object support
  • Index/Unique Key/Primary Key support
  • Pattern matching abstraction
  • Module framework to load advanced functionality on demand
  • Ability to read the information schema
  • RDBMS management methods (creating, dropping, altering)
  • Reverse engineering schemas from an existing database
  • SQL function call abstraction
  • Full integration into the PEAR Framework
  • PHPDoc API documentation

MDB2 – InstallationWiki
How to use PHP and PEAR MDB2

Text_CAPTCHA

Implementation of CAPTCHAs (Completely Automated Public Turing tests to tell Computers and Humans Apart).
Using PEAR’s Text_CAPTCHA to Secure Web Forms

Log

The Log package provides an abstracted logging framework. It includes output handlers for log files, databases, syslog, email, Firebug, and the console. It also provides composite and subject-observer logging mechanisms.
The Log Package
PHPBuilder
Debugging PHP With Firebug
Advanced Logging in PHP with PEAR

LiveUser

LiveUser is a set of classes for dealing with user authentication
and permission management. Basically, there are three main elements that make up this package:

  • The LiveUser class
  • The Auth containers
  • The Perm containers

The LiveUser class takes care of the login process and can be configured to use a certain permission container and one or more different auth containers.
That means, you can have your users’ data scattered amongst many data containers and have the LiveUser class try each defined container until the user is found.
For example, you can have all website users who can apply for a new account online on the webserver’s local database. Also, you want to enable all your company’s employees to login to the site without the need to create new accounts for all of them. To achieve that, a second container can be defined to be used by the LiveUser class.

You can also define a permission container of your choice that will manage the rights for each user. Depending on the container, you can implement any kind of permission schemes for your application while having one consistent API.
Using different permission and auth containers, it’s easily possible to integrate newly written applications with older ones that have their own ways of storing permissions and user data. Just make a new container type and you’re ready to go!

PEAR::LiveUser Wiki
Getting Started with LiveUser Permissions
Authentication
PHP Authentication and Access Control Libraries

Translation2

This class provides an easy way to retrieve all the strings for a multilingual site from a data source (i.e. db).
The following containers are provided, more will follow:

  • PEAR::DB
  • PEAR::MDB
  • PEAR::MDB2
  • gettext
  • XML
  • PEAR::DB_DataObject (experimental)

It is designed to reduce the number of queries to the db, caching the results when possible.
An Admin class is provided to easily manage translations (add/remove a language, add/remove a string).
Currently, the following decorators are provided:

  • CacheLiteFunction (for file-based caching)
  • CacheMemory (for memory-based caching)
  • DefaultText (to replace empty strings with their keys)
  • ErrorText (to replace empty strings with a custom error text)
  • Iconv (to switch from/to different encodings)
  • Lang (resort to fallback languages for empty strings)
  • SpecialChars (replace html entities with their hex codes)
  • UTF-8 (to convert UTF-8 strings to ISO-8859-1)

PEAR::Translation2 tutorials

Validate

Package to validate various data. It includes :

  • numbers (min/max, decimal or not)
  • email (syntax, domain check, rfc822)
  • string (predefined type alpha upper and/or lowercase, numeric,…)
  • date (min, max, rfc822 compliant)
  • uri (RFC2396)
  • possibility valid multiple data with a single method call (::multiple)

An introduction to PEAR’s Validate package

Spreadsheet_Excel_Writer

Spreadsheet_Excel_Writer was born as a porting of the Spreadsheet::WriteExcel Perl module to PHP.
It allows writing of Excel spreadsheets without the need for COM objects.
It supports formulas, images (BMP) and all kinds of formatting for text and cells.
It currently supports the BIFF5 format (Excel 5.0), so functionality appeared in the latest Excel versions is not yet available.
Generating Spreadsheets with PHP and PEAR
What is Spreadsheet_Excel_Writer?

Net_GeoIP

A library that uses Maxmind’s GeoIP databases to accurately determine geographic location of an IP address.
Tutorial from HTML Blog

File_Archive

This library makes it very easy to use, writing simple code, yet the library is very powerful.
It lets you easily read or generate tar, gz, tgz, bz2, tbz, zip, ar (or deb) archives to files, memory, mail or standard output.
File_Archive tutorial
SitePoint » File_Archive

XML_Serializer

XML_Serializer serializes complex data structures like arrays or object as XML documents.
This class helps you generating any XML document you require without the need for DOM.
Furthermore this package can be used as a replacement to serialize() and unserialize() as it comes with a matching

XML_Unserializer that is able to create PHP data structures (like arrays and objects) from XML documents, if type hints are available.
If you use the XML_Unserializer on standard XML files, it will try to guess how it has to be unserialized. In most cases it does exactly what you expect it to do.

Dev Shed XML_Serializer
Instant XML with PHP and PEAR::XML_Serializer

Geolocate your visitors with PHP (part 2)

In the first part of this series I showed how you could get the country of a visitor via his IP address. Now with this precious information, I’ll show you how to map the visitor visually on the world map using Google Maps.


You must sign up for a Google Maps API key if you don’t already have one.

After signing up for the key, include the following code in the head of your page :

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOURKEY" type="text/javascript"></script>

replacing the YOURKEY by the key you obtained.

We then define a container to hold our map with a width of 630px and height of 350px :

<div id="map" style="width:630px;height:350px;"></div>

Till now the overall code for the page, including the first part, is :

<?php
	require_once("Net/GeoIP.php");
	
	if (isset($HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']) && eregi("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", 

$HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'])){
		$ip = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'];
	}
	else{
		$ip = getenv("REMOTE_ADDR");
	}
	
	$geoip = Net_GeoIP::getInstance("./data/GeoIP.dat");

	$country = $geoip->lookupCountryName($ip);
?>

<html>
	<head>
		<title>Google maps</title>
		<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOURKEY" type="text/javascript"></script>	
	</head>
	<body>
		<div id="map" style="width:630px;height:350px;"></div>
	</body>
</html>

Now begins the cool stuff, I’ll show you the complete javascript code and then explain afterwards.

var locator = {    			
	addAddressToMap: function(response) {
		locator.map.clearOverlays();
		if (!response || response.Status.code != 200) {
			//alert("Sorry, we were unable to geocode that address");
		}
		else {
			place = response.Placemark[0];
			point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
			marker = new GMarker(point);
			locator.map.addOverlay(marker);
			marker.openInfoWindowHtml(place.address);
		}
	},

	load: function() {
		if (GBrowserIsCompatible()) {
			locator.map = new GMap2(document.getElementById("map"));
        		locator.map.setCenter(new GLatLng(34, 0), 1);
        		locator.geocoder = new GClientGeocoder();
        		locator.geocoder.getLocations("<?php echo $country; ?>", locator.addAddressToMap);
      		}
    	}
}

We have a nice JSON object with 2 functions in it, namely:

  • load
  • addAddressToMap

The load function

The load function will be called upon loading the page, it will initialize our map, and center it.

locator.map = new GMap2(document.getElementById("map"));
locator.map.setCenter(new GLatLng(34, 0), 1);

We then create an instance of the GClientGeoCoder class which will allow us to obtain geocodes for user specified addresses.

With the object created, we then call the getLocations method with 2 parameters. The first one is the country which we got from the php script and the second parameter being the callback function. In this case our callback function is addAddressToMap.

The addAddressToMap function

The addAddressToMap function is called when the geocoder returns an answer, with response as parameter. The response object contains various information such as the address and the coordinates for the country obtained via the getLocations method.

These coordinates can be accessed via

  • response.Placemark[0].Point.coordinates[1] for longitude and
  • response.Placemark[0].Point.coordinates[0] for latitude

To make things a bit short I’ve placed the response.Placemark[0] in a variable called place :

place = response.Placemark[0];

, thus the coordinates can be accessed via :

place.Point.coordinates[1]
place.Point.coordinates[0]

With these 2 coordinates we create a marker which we’ll plot on the map :

point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
marker = new GMarker(point);
locator.map.addOverlay(marker);

As a bonus we also have a popup showing the country name using the openInfoWindowHtml method. We simply add the following line :

marker.openInfoWindowHtml(place.address);

our final PHP page looks like that :

<?php
	require_once("Net/GeoIP.php");
	
	if (isset($HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR']) && eregi("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$", 

$HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'])){
		$ip = $HTTP_SERVER_VARS['HTTP_X_FORWARDED_FOR'];
	}
	else{
		$ip = getenv("REMOTE_ADDR");
	}
	
	$geoip = Net_GeoIP::getInstance("./data/GeoIP.dat");

	$country = $geoip->lookupCountryName($ip);

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
		<title>my ip address with Google Maps</title>
		<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=YOURKEY" type="text/javascript"></script>

		<script type="text/javascript">
    		//<![CDATA[
    		
    		var locator = {    			
    			addAddressToMap: function(response) {
				locator.map.clearOverlays();
				if (!response || response.Status.code != 200) {
					//alert("Sorry, we were unable to geocode that address");
				}
				else {
					place = response.Placemark[0];
					point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
					marker = new GMarker(point);
					locator.map.addOverlay(marker);
					marker.openInfoWindowHtml(place.address);
				}
			},

			load: function() {
				if (GBrowserIsCompatible()) {
					locator.map = new GMap2(document.getElementById("map"));
        				locator.map.setCenter(new GLatLng(34, 0), 1);
        				locator.geocoder = new GClientGeocoder();
        				locator.geocoder.getLocations("<?php echo $country; ?>", locator.addAddressToMap);
				}
      			}
    		}
   
    		//]]>
		</script>
	</head>
	<body onload="locator.load();" onunload="GUnload();">
		<div id="map" style="width:630px;height:350px;"></div>
	</body>
</html>

After the page has been loaded, we just call the locator.load() function which will initialize the whole process.

Geolocate your visitors with PHP (part 1)

In this short post, I’ll show you how to geolocate your visitors with PHP. First of all let’s have a look at what you’ll need :

  • PEAR GeoIP
  • MaxMind GeoLite Country

Installing PEAR GeoIP

Using your console or using the command prompt type :

pear install http://download.pear.php.net/package/Net_GeoIP-1.0.0RC1.tgz

Obtaining MaxMind GeoLite Country

The database can be downloaded freely here. Download it and put it in the same folder where your script will reside.

The code

<?php
	require_once('Net/GeoIP.php');

	$geoip = Net_GeoIP::getInstance('./GeoIP.dat');
	$ip = getenv('REMOTE_ADDR');
	$country = $geoip->lookupCountryName($ip);

	echo "Hi, you're from ".$country;
?>

Walkthrough

Now let’s go through the lines of code. The first line tells us to include the GeoIP class, which we installed previously and then create a geoip object in line 5 from the database we downloaded.
Next, in line 6 we get the IP address of the visitor and finally we call the lookupCountryName method with the IP address as parameter in line 7 and it will return us the country.

The last line just outputs the country, for example, “Hi, you’re from Mauritius”. That’s it, now you know where your visitor’s from.

In the second part of this article I’ll show you how to use the script to visually map your visitors using Google Maps. You can have a little preview of the script here.