Archive for the 'PHP/MySQL' Category

PHP: Removing All Non-Printable (Special Characters) From String

Friday, February 12th, 2010

I was actually trying to find a way to do this in JavaScript, but eventually gave up. I basically want to remove all non-printable special characters from a string. So for a string like this:

Code:
$str = 'Characters like© and ® are not all®wed.';

I would want ‘Characters like and are not allwed.’. The following matches anything in the ASCII range of 0-31 & 128-255 and removes it.

Code:
$str = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $str); 

Apache: Disabling ETags to Improve Performance

Saturday, January 30th, 2010

By removing the ETag header, you disable caches and browsers from being able to validate files, so they are forced to rely on your Cache-Control and Expires header. Basically you can remove If-Modified-Since and If-None-Match requests and their 304 Not Modified Responses.

Entity tags (ETags) are a mechanism web servers and the browser use to determine whether a component in the browser’s cache matches one on the origin server. Since ETags are typically constructed using attributes that make them unique to a specific server hosting a site, the tags will not match when a browser gets the original component from one server and later tries to validate that component on a different server.

Doing this is simple. First step make sure the Headers mod is enabled:

Code:
a2enmod headers

Then, within your apache2.conf file, add the following:

Code:
Header unset ETag
FileETag None

PHP: Remove New Lines From a String

Tuesday, January 19th, 2010

You would think a function to remove new lines from a string would exist, but surprisingly it doesn’t. My first thought was to use the nl2br function. nl2br “inserts HTML line breaks before all newlines in a string” and to then strip the br’s out. So something like this:

Code:
$string = strip_tags(nl2br($string));

The key word above is “before” though. The function preserves the new lines and just adds a br after it. So I decided to write a function to do it for me:

Code:
function removeNewLines($string) {

    $string = str_replace( "\t", ' ', $string );
    $string = str_replace( "\n", ' ', $string );
    $string = str_replace( "\r", ' ', $string );
    $string = str_replace( "\0", ' ', $string );
    $string = str_replace( "\x0B", ' ', $string );

    return $string;

}

XAMPP: Setting Up Virtual Hosts Using Apache Friends

Thursday, October 29th, 2009

This is something I do often for development, but never actually knew if I was doing it correctly. I think I’ve finally gotten this right. What I want is: To be able to setup VirtualHosts in XAMPP and also define a PHP include path within that. I’m assuming you generally have an idea how to setup a VirtualHost in Apache.

The first step is to modify your Hosts file to point traffic to your local computer. My hosts file is here C:\WINDOWS\system32\drivers\etc\hosts, you’ll have to search for yours.

Code:
127.0.0.1		www.sun.com
127.0.0.1		sun.com

The next step is to define the VirtualHost within the httpd-vhosts.conf file in the conf directory of your XAMPP setup.

Code:
NameVirtualHost *
<VirtualHost *>
	DocumentRoot "C:\xampp\htdocs"
	ServerName localhost
</VirtualHost>
<VirtualHost *>
	DocumentRoot "C:\xampp\htdocs\sun"
	ServerName www.sun.com
	ServerAlias sun.com
        ErrorDocument 404 /error.php
	<Directory "C:\xampp\htdocs\sun">
		Order allow,deny
		Allow from all
	</Directory>
	<Directory "C:\xampp\htdocs\sun">
                 php_value include_path ".;C:\php\pear;C:\htdocs\sun\xx"
	</Directory>
</VirtualHost>

Using a php_value directive you can define the include path for that VirtualHost right from conf file – thank God.

MySQL: Backup Database and Upload to Amazon S3 via PHP

Saturday, August 29th, 2009

I wrote a post a few years ago about a quick way to backup a MySQL database using email. Since then I’ve updated that script to upload the file to Amazon S3 instead of emailing it. I use an Amazon S3 PHP Class you can find here to make it happen. Your also going to need cURL enabled on your server. On Ubuntu/Debian that’s as easy as:

Code:
sudo apt-get install php5-curl 

Here is the script:

Code:
require_once 'S3.php';

if (!defined('awsAccessKey')) define('awsAccessKey', 'xxxxxxxxxxxxxxxxxxx');
if (!defined('awsSecretKey')) define('awsSecretKey', 'xxxxxxxxxxxxxxxxxxx');
//
// Check for CURL
if (!extension_loaded('curl') && !@dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
	exit("\nERROR: CURL extension not loaded\n\n");
}

$tmpDir = "/tmp/";
$user = "dbuser";
$password = "dbpassword";
$dbName = "dbname";
$prefix = "db_";

$sqlFile = $tmpDir.$prefix.date('Ymd_hisA').".sql";
$attachment = $tmpDir.$prefix.date('Ymd_hisA').".tgz";

$creatBackup = "mysqldump -u ".$user." --password=".$password." ".$dbName." > ".$sqlFile;
$createZip = "tar cvzf $attachment $sqlFile";
exec($creatBackup);
exec($createZip);

if (!file_exists($attachment) || !is_file($attachment)) {
	die("ERROR: No file");
}

$s3 = new S3(awsAccessKey, awsSecretKey);
$result = false;
if ($s3->putObjectFile($attachment, 'bucket-name', baseName($attachment), S3::ACL_PRIVATE)) {
	$result = true;
}

unlink($sqlFile);
unlink($attachment);

Apache: Stripping/Remove the www from URLS

Wednesday, August 19th, 2009

For reasons I won’t go into, I wanted to force Apache to strip the www from the URLs. So if someone typed in http://www.abc.com, Apache would automatically send them to http://abc.com. First thing to do is make sure ModRewrite is enabled, once that’s done simply put the following in your VirtualHost configuration or in the associated .htaccess file:

Code:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.+)$
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

Setting Different PHP Include Paths per Apache Virtual Hosts

Wednesday, July 15th, 2009

I was always curious how to set different PHP include paths per Virtual Host in Apache. I didn’t want to use an .htaccess file hack or the PHP function set_include_path. After some digging, I came across a post on a mailing list showing how it’s done using a Directory directive:

Code:
# PHP OPTIONS ###########################
    <Directory /path/to/site>
        php_value include_path ".:/path/to/site:/another/path"
        php_admin_value session.entropy_file "/dev/urandom"
        php_admin_value session.entropy_length "512"
        php_admin_value session.auto_start 1
        php_admin_value session.use_cookies 1
        php_admin_value session.use_only_cookies 1
        php_admin_value session.cookie_lifetime 0
        php_admin_value session.cookie_secure 1
    </Directory>
# PHP OPTIONS ###########################

Setting Up Memcached on Ubuntu/Debian and Windows XAMPP

Monday, March 9th, 2009

I have a big problem with writing things down. This inevitably leads me to spending excessive amount of time looking all over the internet for how to solve a problem. Most recently I was trying to remember the steps to get Memcached going on my Debian server and on my laptop.

Luckily I came across this comment on php.net, which explains nicely how to get this going on Debian/Linux. The only thing I needed to do was make sure g++ was installed (i.e. apt-get install g++). Here are the steps:

Code:
-------------------------
# Prerequisite Install
-------------------------
# Download & install libevent (memcached dependency)
wget http://www.monkey.org/~provos/libevent-1.4.8-stable.tar.gz
tar xfz libevent-1.4.8-stable.tar.gz
cd libevent-1.4.8-stable
./configure && make && sudo make install

# Create a symlink to libevent
sudo ln -s /usr/local/lib/libevent-1.4.so.2 /usr/lib

# Download & install memcached
wget http://danga.com/memcached/dist/memcached-1.2.6.tar.gz
tar xfz memcached-1.2.6.tar.gz
cd memcached-1.2.6
./configure && make && sudo make install

# Run memcached as a daemon (d = daemon, m = memory, u = user, l = IP to listen to, p = port)
memcached -d -m 1024 -u root -l 127.0.0.1 -p 11211

-------------------------
# PHP5-Memcache Install
-------------------------
# Download the extension module
apt-get install php5-memcache

# Edit /etc/php5/conf.d/memcache.ini and uncomment the following line by removing the semi-colon
extension=memcache.so

# Restart apache
/etc/init.d/apache2 restart

-------------------------
# Test Install
-------------------------
# Create a file 'memcache_test.php' in your webroot and paste the following:
<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

$version = $memcache->getVersion();
echo "Server's version: ".$version."<br/>\n";

$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;

$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/>\n";

$get_result = $memcache->get('key');
echo "Data from the cache:<br/>\n";

var_dump($get_result);
?>

In Windows (assuming you have XAMPP installed) go into your php.ini (check phpinfo for location) file and un-comment the following:

Code:
...
extension=php_memcache.dll
...
[Memcache]
memcache.allow_failover = 1
memcache.max_failover_attempts=20
memcache.chunk_size =8192
memcache.default_port = 11211
...

Then head to Jellycan Code and download the Windows memcached port (binary). At this point you should be able to launch the .exe and run the sample code above.

RSA: Encrypting in JavaScript and Decrypting in PHP

Monday, October 27th, 2008

I came across a really cool JavaScript library a while back that allows you to do client-side RSA encryption & decryption. If you don’t know much about RSA, read up on it here. Essentially, it’s an algorithm for public/private key encryption/decryption. You encrypt using the Public Key and Modulus and decrypt using the Private Key and Modulus.

More often than not, you would want to encrypt client-side (browser) and decrypt server-side. For my purposes, I wanted to encrypt passwords 13 characters or less in JavaScript and decrypt them in PHP. The creator of the RSA library also created a convenient Windows application that generates RSA keys for you. Using that program I created the following 128bit keys:

e = Public Key = 553799486327459813656784787218239817 (6aa86c39bbe678f7f7967a587a1149)
d = Private key = 1401845535567450041611005523755666809 (10dfc5235ef69148bdfdc6832860d79)
m = Modulus = 11570601966616835094916890432003700913 (8b46ab8a951615d07b66bdd2420f8b1)

By default the RSA library outputs encrypted strings in Hex, but because there is no built in PHP function to convert from Hex to Binary, I decided to modify the RSA.js file slightly (within the encryptedString function – line 62) to output the full Integer:

var text = key.radix == 16 ? biToDecimal(crypt)/*biToHex(crypt)*/ : biToString(crypt, key.radix);

The Key Generator also conveniently creates the JavaScript needed to create the new key pair. I’ve removed the decryption (Private) key:

setMaxDigits(19);
key = new RSAKeyPair(”6aa86c39bbe678f7f7967a587a1149″, “”, “8b46ab8a951615d07b66bdd2420f8b1″);
w.value = encryptedString(key,”1234567890123″ + “\x01″);

The trick here is adding “\x01″ to the end of the string you want to encrypt. The PEAR library used to decrypt the encrypted string will look for this, and throws an error if not found. That said, the above encrypted string is:

1276850306890326374886324100793107985

The PEAR package used to decrypt this string is called Crypt_RSA. You install this just like any other PEAR package:

PEAR install Crypt_RSA

The package depends on one of 3 Math libraries (BCMath, GMP or big_int), of which BCMath is slowest but installed by default (at least in my version of PHP 5.2.0-8+etch13 & XAMPP-win). The Crypt_RSA package works in binary, so the keys and encrypted text needs to be converted before calling the package. The following code converts the Integers to Binary and performs the decryption. Bare in mind your dealing with very large numbers, so you need to use one of the above Math libraries to work with them.

require_once ‘Crypt/RSA.php’;
//
$wrapper_name = “BCMath”;
$math_obj = &Crypt_RSA_MathLoader::loadWrapper($wrapper_name);
//
$d = $math_obj->int2bin(”1401845535567450041611005523755666809″);
$m = $math_obj->int2bin(”11570601966616835094916890432003700913″);
//
$pk = new Crypt_RSA_Key($m, $d, “private”, $wrapper_name);
$rsa_obj = new Crypt_RSA;
$rsa_obj->setParams(array(’dec_key’ => $pk));
$dec = $rsa_obj->decryptBinary($math_obj->int2bin(”1276850306890326374886324100793107985″));
echo $dec;

You can download my sample code here.

Installing PECL Filter on Debian Linux (AMD64)

Thursday, October 9th, 2008

I just finished installing the PECL filter extension on my Debian install (AMD64), and by God, it was painful. This process was so brutal with so many ways to screw up. Here are the steps:

Install php5-dev package. During the process of not figuring out what was going on, I also installed the php4-dev package. I’m pretty sure I only needed php5-dev.

Download PCRE – Perl Compatible Regular Expressions from here. Be sure you have g++ installed (not just gcc as I was getting a strange error). Extract, configure, make and make install. If your running AMD64, be sure to compile using the -fPIC flag. See here for information why. Filter will look for the library in /usr/local/, so you’ll have to setup a link or copy it from /usr/local/lib/ so the PECL install can find it.

The Filter package also looks for the header files from the php_pcre extension. The only way I found to get at these header files was to download the PHP source. So depending on what version of PHP you have, go here and download the zip. Copy the entire pcre folder from within the extension (ext) folder into your /usr/include/php5/ext/ folder.

Now it’s time to attempt the actual PECL Filter install. If your doing this from the tarball and your running on an AMD64, as above, be sure to add the -fPIC flag. I used the PECL installer, so I ran: pecl install filter. Since the package is not “stable” yet, you’ll need to point right to the channel, just read the message, in my case it was: pecl install channel://pecl.php.net/filter-0.11.0. After the compile/install is done, add extension=filter.so to your php.ini file. If you can’t find it, type find / -name php.ini from your command line.

That’s it. I may have forgotten a step, if so add a comments please.

Book: Learning PHP Data Objects

Thursday, January 3rd, 2008

I don’t normally read programming books, but I was given a copy of Learning PHP Data Objects as a gift a couple moths ago and thought I’d give it a spin. Though the book is a beginners guide to PDO, it requires the reader to have a working knowledge of PHP and Data Abstraction. I was particularly curious to read more about PDO, since I had always used the PEAR database abstraction classes (now MDB2), and wanted to see what, if anything, I was missing out on. I know what your thinking: PDO is compiled into PHP and the PEAR classes need to be parsed just like any other PHP script. This is true, but when you add in op-code level caching like APC, I doubt the speedup is THAT drastic (though I could be very wrong). As a beginners guide, I would have liked the book to compare the various database abstraction options available (i.e. PDO, MDB2, ADOdb, etc.) and provided a quick cost/benefit analysis. Overall the book is a good beginners guide and will teach you what you need to know to get started quickly.

Apache SVN: Auto-Update Server Copy on Commit

Tuesday, October 2nd, 2007

It seems these days I spend more time figuring out annoying problems rather than doing any real work. The following gave me another big headache: Getting SVN to auto-update properly via it’s hooks. SVN provides you the ability to specify hooks after certain events occur with the repository in question. For example, say you have a live application under version control and you want SVN to auto-update the live copy (on the server) after every commit. I guess that makes sense, especially if you want to develop and test in your production environment, on the fly.

In the directory were your repository exists there should be a hooks directory. This directory includes a bunch of tmpl files that get called depending on the event that just occurred. The file that I cared about was the post-commit.tmpl file.

Assuming your running SVN using Apache, then most likely when your post-commit script gets called it will be executed using the user www-data. This is important because it means your repository needs to be checked out via the same user to ensure no permission problems occur. Assuming that OK, then add the following line to your post-commit.tmpl file:

Code:
/usr/bin/svn update <path to repo> --username xxxxxx --password xxxxxx

Hardcoding your SVN password in the file is probably not the best idea, but if your the only one who would have access to the file, then who cares. Notice how I put a full path to SVN, that’s because when the hook scripts get called all environment variables, etc. get removed. The next step, and probably most important, rename the file removing the .tmpl extension and change the ownership so the file becomes executable.

Code:
cp post-commit.tmpl post-commit
chmod +x post-commit

That should do it, so when you update your repository, SVN should auto-update your live working copy. Most likely you’ll run into problems, if so check the links below for more info.

Helpful Link #1
Helpful Link #2
Helpful Link #3

PHP: Creating a singleton class for serialization

Thursday, September 20th, 2007

There’s a lot of examples on the internet about creating and using the singleton pattern within your application. From the PHP Docs:

The Singleton pattern applies to situations in which there needs to be a single instance of a class. The most common example of this is a database connection. Implementing this pattern allows a programmer to make this single instance easily accessible by many other objects.

Within any class you want to have use the singleton pattern, just add a getInstance method, like I have in the Obj code listing below. To access that instance use the scope resolution operator:

Code:
$obj = Obj::getInstance();

A problem arises when you want to serialize/unserialize that object from the session variable. The issue is this: When unserialize is called, PHP will attempt to reconstruct the object in question – everything will get created properly but the $instance variable will now be NULL because it would be pointing to the object reference from the previous page. So the next time you would call getInstance, the function would return an entirely new object with no serialized data. All the serialized data would exist in whatever variable the unserialize function was assigned to initially.

Once you understand this subtlety fixing the problem is easy. Create a function called setInstance, which takes in an object reference and assigns the object to the static $instance variable within the class. So once you unserialize your object from the session, immediately call setInstance to let the class know the object exists:

Code:
$obj = unserialize($_SESSION['SessionControl']);
$obj->setInstance($obj);

The full code listings follow so you can test this out. Someone out there is probably thinking, why not just called setInstance from within the __wakeup function with $this as a parameter? That won’t work, the object won’t serialize properly.

Code:
<?php

class Obj {

        static private $instance = NULL;

        public function __construct() { }

	public static function getInstance() {
		if (self::$instance == NULL) {
			self::$instance = new Obj;
		}
		return self::$instance;
	}

	public function setInstance($o) {
		self::$instance = $o;
	}

        public function __sleep() {
		return array_keys(get_object_vars($this));
       }

       public function __wakeup() { }
}

?>

Code:
<?php

require 'obj.class.php';

session_start();

if(!empty($_SESSION['SessionControl'])) {
        $obj = unserialize($_SESSION['SessionControl']);
	$obj->setInstance($obj);
} else {
	$obj = Obj::getInstance();
}

function save_session() {
	$obj = Obj::getInstance();
	$_SESSION['SessionControl'] = serialize($obj);
}

register_shutdown_function(save_session);

?>

PHP: Including scripts from within class functions

Monday, September 3rd, 2007

This surprised me today: Using PHP you can include scripts from within a class functions and access the included functions globally. It seems to go against what I feel should occur, but it works perfectly fine. I posted on a discussion forum at devshed to see if anyone has some insight into this.

temp_include.php:

Code:
<?php

function test_funct() {
    echo "function called";
}

?>

Main script:

Code:
<?php

Class ABC {
    public function __construct() {
        require_once 'temp_include.php';
    }
}

$o = new ABC();
test_funct();

?>

PHP: Caching is my new best friend

Wednesday, August 29th, 2007

This time around, I’m being proactive about programming caching into my code. From what I’ve read APC has the best performance in terms of object level caching, but Memcache is built with a distributed architecture allowing it to scale with relative ease. In any case, I’m using Memcache for object level caching, APC for opcode level caching and XDebug for performance profiling. I use http_load to test multiple fetches in parallel and to see the throughput of the server. I ran my code using 5 parallel fetches for a total of 1000 fetches on my development server. The improvement I found through APC (for opcode caching only) was drastic:

Without APC (comment out extension=apc.so):

Code:
root@fork:/home/dev/http_load# ./http_load -parallel 5 -fetches 1000 url_file
1000 fetches, 5 max parallel, 451000 bytes, in 58.1554 seconds
451 mean bytes/connection
17.1953 fetches/sec, 7755.09 bytes/sec
msecs/connect: 0.154203 mean, 47.333 max, 0.031 min
msecs/first-response: 290.431 mean, 13220.5 max, 57.739 min
HTTP response codes:
  code 200 -- 1000

With APC (add extension=apc.so):

Code:
root@fork:/home/dev/http_load# ./http_load -parallel 5 -fetches 1000 url_file
1000 fetches, 5 max parallel, 451000 bytes, in 10.8297 seconds
451 mean bytes/connection
92.3386 fetches/sec, 41644.7 bytes/sec
msecs/connect: 0.107207 mean, 0.205 max, 0.031 min
msecs/first-response: 54.0108 mean, 6252.95 max, 10.541 min
HTTP response codes:
  code 200 -- 1000

Fetches per second went from 17.2 to 92.3 and milliseconds per first response went from 290.4 to 54.0. Granted these results are somewhat anecdotal because their based on my application and my current dev-server setup. Any way you look at it though the improvement is very impressive.

PHP: Double quotes vs Single quotes

Monday, August 20th, 2007

If you don’t know the difference between using double quotes or single quotes when using Strings in PHP, you should. The PHP Manual page for Strings covers all this, but basically strings created with double quotes will be parsed by PHP. This example shows what I mean:

Code:
// they both output 'Yahoo Google'
$str = 'Google';
echo 'Yahoo' . $str;
echo "Yahoo $str";

At first glance you might think, who cares? The key note is deep in the manual page:

Parsing variables within strings uses more memory than string concatenation. When writing a PHP script in which memory usage is a concern, consider using the concatenation operator (.) rather than variable parsing.

PHP: Sorting an array of objects by a method/member

Sunday, August 19th, 2007

Earlier today I was looking to sort an array of object by a given datetime member. After a couple quick tests I realized that PHP was capable of comparing MySQL DATETIME strings natively. I guess that makes sense, since all they really have to do is convert the string to a timestamp via strtotime. In any case, after a bit of searching I found a method similar to the one below in a comment posted on the PHP Sort manual page. I changed the method a bit to compare using a public class method, sort in descending order and return a new array. I hard coded the function name cause from what I know you can’t pass in the function name as a parameter (you can if it was a key).

Code:
function sortObject($data) {
	for ($i = count($data) - 1; $i >= 0; $i--) {
		$swapped = false;
		for ($j = 0; $j < $i; $j++) {
			if ( $data[$j]->getTime() < $data[$j + 1]->getTime() ) {
				$tmp = $data[$j];
                $data[$j] = $data[$j + 1];
                $data[$j + 1] = $tmp;
                $swapped = true;
			}
		}
		if (!$swapped) {
			return $data;
		}
	}
}

Here is an example of the above function sorting four datetime strings:

Code:
class DObject {

	private $dt;

	public function __construct($d) {
         $this->dt = $d;
    }

	public function getTime() {
		return $this->dt;
	}

}

$date1 = '2009-08-05 03:24:57';
$date2 = '2006-08-05 23:44:56';
$date3 = '2007-08-05 20:14:56';
$date4 = '2005-02-10 12:24:06';

$toSort = array();

array_push($toSort, new DObject($date1));
array_push($toSort, new DObject($date2));
array_push($toSort, new DObject($date3));
array_push($toSort, new DObject($date4));

echo "<pre>";
print_r($toSort);
$result = sortObject($toSort);
print_r($result);
echo "</pre>";

Object-Oriented Features in PHP 5

Thursday, August 2nd, 2007

I came across a good writeup on linuxjournal.com talking about the OO features/capabilities in PHP 5. I guess the most important thing to note is that objects (i.e. objects of classes, not arrays) are now passed by reference. The writeup, which was taken from the book Object-Oriented PHP by Peter Lavin, explains their rational for doing this and how the entire scripting engine underlining PHP had to be re-written. All other types of variables are still passed by value (including arrays), but you can easily pass them by reference by adding an & to the function definition.

Code:
$tempArr = array();
$tempArr[0] = 1982;
$tempArr[1] = 2007;

echo "originally:";
printArray($tempArr);
tempFunc2($tempArr);
echo "after chang in function";
printArray($tempArr);

function tempFunc2(&$obj) {

	$obj[0] = 1;
	$obj[1] = 2;
}

function printArray($ta) {
	echo "<pre>";
	print_r($ta);
	echo "</pre>";

}

A closer look into what Google Adwords charges..

Saturday, March 10th, 2007

This is interesting, though on a small scale, it’s still relevant. I run Google Adwords (display ads on specific search terms with Google) for a service I created called WebBasedCron. A little while ago, I decided to start tracking what ads were really being clicked — i.e. when an advertisement was clicked, it would send them to a special URL (ex. www.webbasedcron.com/?action=advwbc). Then I would use PHP code like the following to record the persons IP, the date, time and their session id.

Code:
if ( $read_action == "advwbc" ) {
        $session = $user->db->quote(session_id());
        $ip = $user->db->quote($_SERVER['REMOTE_ADDR']);
        $date = $user->db->quote(date("'Y-m-d'"));
        $time = $user->db->quote(date('H:i:s'));
        $sqlInsert = "INSERT INTO webcron_google(date,time,ip,session) VALUES ($date,$time,$ip,$session)";
        $user->db->query($sqlInsert);
}

The session is important because it tells me if the advertisement was clicked in the same instance of the browser or not (when you restart your browser, you get a new session). So lets look at the results for March 9th (yesterday). I changed nothing, only hid half the persons IP address.

Code:
2007-03-09  	04:16:35  	211.30.xxx.xx  	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	04:17:20 	211.30.xxx.xx 	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	04:17:47 	211.30.xxx.xx 	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	04:18:07 	211.30.xxx.xx 	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	04:18:10 	211.30.xxx.xx 	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	04:18:13 	211.30.xxx.xx 	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	04:18:34 	211.30.xxx.xx 	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	04:18:36 	211.30.xxx.xx 	9fbe09012f7ce71854b1e040b0b0fe3c
2007-03-09 	07:47:21 	193.71.xx.x 	 1895a2c135512d29fa7002e6a8126e65
2007-03-09 	09:51:47 	59.144.xxx.xxx 	b5c090a6f26d83b890fd2faf79c17464

You may notice, that the first 8 lines were from the same IP address (211.30.xxx.xx) clicked between 04:16:35 to 04:18:36. It’s easy to see this person got pretty click happy, clicking the ad, hitting back, clicking the ad, etc. Furthermore, the session id is the same for all the 8 clicks, which means he/she was using the same browser instance. I would expect Google to be able to detect this type of click fraud and only charge me for 2 legitimate clicks, the ones placed at 07:47:21 and 09:51:47 (not from 211.30.xxx.xx). The strange part, is I was charged for 4 clicks that day. That means of the 8 illegitimate clicks, Google charged me for 2 of them.

Believe me, at an average cost per click of $0.11, it really doesn’t matter, but I can imagine for larger companies, Google must be making a fortune off these people. Its really hard to side with Google on this, I mean if they deemed 6 of those clicks illegitimate, why not the remaining 2?? Do people really click the same advertisement 8 times in 2 minutes, with many of them 3 seconds apart? It’s easy to see that even through blatant click fraud Google shamelessly makes money.

Using PEAR on a shared host

Tuesday, February 27th, 2007

I’ve had a couple people ask this question and I thought I’d post a quick answer. I had this problem also, back when I made StockBoulevard (now I manage my own server, Ubuntu Linux). I used PEAR to develop my application on my laptop, but when the time came to go live, my hosting provider didn’t have PEAR installed. What you need to remember, is that PEAR is just PHP scripts, there’s no compiled DLLs, etc. So all you need to do, is download the PEAR source files from pear.php.net and FTP them to your webserver. Just put everything in a directory called PEAR in your root and explicitly point your include:

Code:
<?php

// require_once("MDB2.php");
require_once("../../PEAR/MDB2.php");

....
......

?>

Friday wrap-up #2

Friday, October 20th, 2006

CASCON was running this week from Monday to Thursday. I didn’t realize this was a free conference for everyone, including people outside IBM. I saw a bunch of professors from McMaster also, some were giving talks.

I went to the Ruby on Rails workshop and it was going OK until one of the presenters starting comparing Ruby on Rails (RoR) to PHP. People need to get something straight: Ruby is the programming language and Rails is a framework. Comparing RoR to PHP isn’t fair, since PHP is the programming language with no framework. If you’re going to compare them, make sure your using some type of template engine like Smarty, etc.

Tuesday, Wednesday and Thursday I had a display at the Technology Showcase from 11:30am to 1:30pm, presenting WDSC and JWL. The experience was good, I met a lot of great people really interested in AJAX and JSF.

Doug Crockford is a smart guy, he’s a JavaScript guru and the creator of JSON. Earlier this year he wrote a paper describing JSONRequest, here’s the abstract:

XMLHttpRequest has a security model which is inadequate for supporting the next generation of web applications. JSONRequest is proposed as a new browser service that allows for two-way data exchange with any JSON data server without exposing users or organization to harm. It exchanges data between scripts on pages with JSON servers in the web. It is hoped that browser makers will build this feature into their products in order to enable the next advance in web application development.

It’s a good read and not a bad idea (though received a lot of criticism). There has also been heavy discussion about this on the Dojo mailing list. Doug’s personal website is filled with great JavaScript articles and resources – especially this article on objects in JavaScript.

I read Chapter 5 of Roy Fielding’s dissertation, which introduced REST or Representational State Transfer. REST is a lot like the Relational Database, conceptually its easy, but has the potential to revolutionize how we do certain things.

How To: Making a PHP REST client to call REST resources

Friday, October 20th, 2006

A lot of companies these days (including Amazon and Yahoo!) are exposing their web services in the form of REST resources. At a high level REST is pretty easy to understand, all you’re doing is exposing a web service in the form of a URL. Users can then query this URL, through HTTP methods like GET and POST. REST calls generally return some type of XML or Object Encoding like JSON.

An example would be Yahoo!’s Geocoding API, with the following URL:

Code:
http://api.local.yahoo.com/MapsService/V1/geocode?appid=YahooDemo&street=701+First+Street&city=Sunnyvale&state=CA

I would get:

Code:
<Result precision="address">
   <Latitude>37.416384</Latitude>
   <Longitude>-122.024853</Longitude>
   <Address>701 FIRST AVE</Address>
   <City>SUNNYVALE</City>
   <State>CA</State>
   <Zip>94089-1019</Zip>
   <Country>US</Country>
</Result>

So Yahoo! exposes the Geocode URL and allows you to query this resource using URL parameters like appid and street. Dynamically building your URL to query a given resource is OK, generally that’s what people do, like the following:

Code:
$base = 'http://xml.amazon.com/onca/xml3';
$query_string = "";

$params = array( 'ManufacturerSearch' => "O'Reilly",
    'mode'  => 'books',
    'sort'  => '+salesrank',
    'page'  => 1,
    'type'  => 'lite',
    'f'     => 'xml',
    't'     => 'trachtenberg-20' ,
    'dev-t' => 'XXXXXXXXXXXXXX' ,
);

foreach ($params as $key => $value) {
    $query_string .= "$key=" . urlencode($value) . "&";
}

$url = "$base?$query_string";
$output = file_get_contents($url);

The problem here, is that REST is meant to take advantage of HTTP methods GET, POST, PUT, DELETE, etc.. When people are showing examples which dynamically build queries and call file_get_contents, the average user doesn’t appreciate (understand) what type of request is being made. Do they care? Should they care? We’ll that’s another story. Eventually though, more intense REST resources will become widely available, and it will be critical the user (developer) understands if their making a POST or PUT request.

I came across a great PEAR package the other day called HTTP_REQUEST, which among many things supports GET/POST/HEAD/TRACE/PUT/DELETE, basic authentication, proxy, proxy authentication, SSL, file uploads and more. Using this package, I got started on a simple wrapper class called RESTclient, which gives intuitive support for making REST resource calls.

So if I was going to use RESTclient to call the Geocode API above, it would look like this:

Code:
<?php

require_once "RESTclient.php";

$rest = new RESTclient();

$inputs = array();
$inputs["appid"] = "YahooDemo";
$inputs["street"] = "701 First Street";
$inputs["city"] = "Sunnyvale";
$inputs["state"] = "CA";

$url = "http://api.local.yahoo.com/MapsService/V1/geocode/"
$rest->createRequest("$url","POST",$inputs);
$rest->sendRequest();
$output = $rest->getResponse();
echo $output;

?>

At this point, you might be thinking, who cares — what’s the difference between using a loop to dynamically generate the URL or RESTclient. There are lots of reasons, first off, I can easily call the Geocode resource again using another address just by changing:

Code:
$inputs["street"] = "1600 Amphitheatre Parkway";
$inputs["city"] = "Mountain View";

There was no need to re-generate the URL. Furthermore, I’m explicitly specifying a POST request. Just as easily I can make a PUT, DELETE, etc. request on a given resource by changing the createRequest method parameters.

The class below is RESTclient. Note, I put this together to prove a point, it still needs some work if you plan on using it.

Code:
<?php

require_once "HTTP/Request.php";

class RESTClient {

    private $root_url = "";
    private $curr_url = "";
    private $user_name = "";
    private $password = "";
    private $response = "";
    private $responseBody = "";
    private $req = null;

    public function __construct($root_url = "", $user_name = "", $password = "") {
        $this->root_url = $this->curr_url = $root_url;
        $this->user_name = $user_name;
        $this->password = $password;
        if ($root_url != "") {
            $this->createRequest("GET");
            $this->sendRequest();
        }
        return true;
    }

    public function createRequest($url, $method, $arr = null) {
        $this->curr_url = $url;
        $this->req =& new HTTP_Request($url);
        if ($this->user_name != "" && $this->password != "") {
           $this->req->setBasicAuth($this->user_name, $this->password);
        }        

        switch($method) {
            case "GET":
                $this->req->setMethod(HTTP_REQUEST_METHOD_GET);
                break;
            case "POST":
                $this->req->setMethod(HTTP_REQUEST_METHOD_POST);
                $this->addPostData($arr);
                break;
            case "PUT":
                $this->req->setMethod(HTTP_REQUEST_METHOD_PUT);
                // to-do
                break;
            case "DELETE":
                $this->req->setMethod(HTTP_REQUEST_METHOD_DELETE);
                // to-do
                break;
        }
    }

    private function addPostData($arr) {
        if ($arr != null) {
            foreach ($arr as $key => $value) {
                $this->req->addPostData($key, $value);
            }
        }
    }

    public function sendRequest() {
        $this->response = $this->req->sendRequest();

        if (PEAR::isError($this->response)) {
            echo $this->response->getMessage();
            die();
        } else {
            $this->responseBody = $this->req->getResponseBody();
        }
    }

    public function getResponse() {
        return $this->responseBody;
    }

}
?>

How to: Building dynamic PHP objects and URL decoding example

Friday, October 6th, 2006

PHP is a powerful programming language; with every release I’m amazed with the new power and functionality. The ability to build dynamic objects (the way I’ll describe) I believe was introduced as of PHP 5. In any case, this is good stuff. There are lots of reasons why you would want to create a dynamic object, in my example below; you’ll see how to create a dynamic object of the URL query parameters.

At the heart of building dynamic PHP objects are the PHP Magic Methods. From the PHP manual:

The function names __construct, __destruct (see Constructors and Destructors), __call, __get, __set, __isset, __unset (see Overloading), __sleep, __wakeup, __toString, __set_state, __clone and __autoload are magical in PHP classes. You cannot have functions with these names in any of your classes unless you want the magic functionality associated with them.

Magic methods get called automatically through the parser when certain events occur. For example, just before you transition pages all objects you’ve created will call their respective __sleep methods. Most likely you wouldn’t have this method defined, so nothing would happen.

So now lets look at what happens when a certain method (or variable) of a given PHP object is called. Take the following code as an example:

Code:
$x = new obj();
$x->method1();
$x->var1;

When a method of a given object is called (like method1) the first thing the parser does is look for the associated name in the instance of the object. If the method is found, then the parser gives control to the method. If the method is not found, then the __call function is called with the function name and input values as a parameter. If this function returns true, then the object will return successfully. If a __call function does not exist, the parser will check the parent class (if exists) and so forth.

Similarly, if a variable of an object is requested (like var1) the parser looks in the object for a variable with that name. If a variable does not exist, the __get method is called with the name of the variable as a parameter, and so forth.

You should be able to see how we can now simulate (fake) the existence of methods and variables by using these magic methods. The code below shows the parent class G_Dynamic. This class would be the parent to specific subclasses that would require dynamic method/variable access.

Code:
<?php

/*  */

/**
 *
 * PHP versions 5.1.4
 *
 * George A. Papayiannis
 *
 * This class provides the magic functions needed to create
 * a dynamic object.  Subclasses would extend this object
 * and call the constructor with a parsed array.  See
 * g_url_decode.class.php for an example of creating a
 * dynamic object from the URL query string.
 *
 */

/**
 * Class definition
 */

class G_Dynamic {

    private $param = array();

    public function __construct($init) {
        $this->param = $init;
    }

    private function __get($name) {
        if (isset($this->param[$name])) {
            $res = $this->param[$name];
        } else {
            $res = false;
        }
        return $res;
    }

    private function __set($name, $val) {
        if (isset($this->param[$name])) {
            $this->param[$name] = $val;
            $res = true;
        } else {
            $res = false;
        }
        return $res;
    }

    private function __isset($name) {
        return isset($this->param[$name]);
    }

    private function __unset($name) {
        unset($this->param[$name]);
    }

    private function __call($name, $var) {
        // add code to simulate function call
        // return TRUE for success
    }

}

?>

As an example, I created a subclass to G_Dynamic called G_URL_Decode. This class takes the URL query string as input, parses it into an array and calls the parents (G_Dynamic) constructor. The code for G_URL_Decode is below:

Code:
<?php

/*  */

/**
 *
 * PHP versions 5.1.4
 *
 * George A. Papayiannis
 *
 * This class extends the G_Dynamic class to create a
 * dynamic object of the URL query string.  In another
 * file, you would have:
 *
 * require_once "g_url_decode.class.php";
 * $x = new G_URL_Decode($_SERVER['QUERY_STRING']);
 *
 * then you could have $x->(url param name) to access
 *
 */

require_once "g_dynamic.class.php";

/**
 * Class definition
 */

class G_URL_Decode extends G_Dynamic {

    private $queryParam = array();

    public function __construct($qs) {
         parent::__construct($this->parseURL($qs));
    }

    public function getQueryParam() {
        return $this->queryParam;
    }

    private function parseURL($qs) {
        $this->queryParam = array();
        $qs_parsed = explode("&", $qs);
		foreach ($qs_parsed as $value) {
			$paramVal = explode("=",$value);
			if (array_key_exists(1,$paramVal)) {
				$this->queryParam[htmlspecialchars(urldecode($paramVal[0]))] = htmlspecialchars(urldecode($paramVal[1]));
			}
		}
		return $this->queryParam;
    }
}

?>

Once the URL query string is successfully parsed, you can access the parameter names through the object. The code to bring it all together is below.

Code:
<?php

require_once "g_url_decode.class.php";
$x = new G_URL_Decode($_SERVER['QUERY_STRING']);
echo $x->var1;

?>

Using this as a base, you should be able to build some pretty cool dynamic objects.
Click here to download the source.

The best (free) PHP IDE..

Friday, October 6th, 2006

Update (Mar. 5/07): Eventually you would need some type of version control and I just saw an Eclipse Plugin for SVN.

I’ve been a long time fan of simple development environments. Give me EditPlus with syntax highlighting and I’m good to go. I’ve always known about TM (Target Management) or better known around here at Remote Systems Explorer. As the name says, the plug-in lets you work with remote systems from within Eclipse. So no matter were I am, I can connect to my server (through SSH, FTP, etc.) and work remotely. I can even launch a shell from within Eclipse! The TM group hasn’t released 1.0 yet, but it should be there within a couple weeks.

Along the same lines, a couple weeks ago I got exposed to the PHP IDE project. This is another Eclipse project in the works, being sponsored mainly by Zend with support from IBM and others. Their in version 0.7 right now, and expect to release version 1.0 sometime near the end of the year. The plug-in is stable, but I’ve noticed small problems ranging from automatic formatting issues to context assist errors. Aside from the small problems, this plug-in is amazing — The syntax highlighting is great, there is automatic publishing and an integrated debugger in the works.

With RSE + PHP IDE almost at 1.0, I have a feeling Eclipse will soon be my development environment of choice — If only Eclipse loaded as fast as EditPlus. Here are some screen shots of Eclipse + TM + PHP IDE. Click the image to see a large shot.


Eclipse


Eclipse

How to: PHP on the i5 – The i5 PHP API Toolkit and Calling RPG/CL Programs

Monday, September 25th, 2006

Before I begin to talk about PHP on the i5, a little history is in order. PHP was created by Rasmus Lerdorf in 1994 to replace a personal set of Perl scripts he used to maintain his website. He officially released version 1.0 in 1995 as a set of CGI binaries written in C, under the GNU General Public License. In 1997 two developers at the Israel Institute of Technology, Zeev Suraski and Andi Gutmans, re-wrote the parser releasing PHP 3.0 in June 1998. Zeev and Andi went on to create Zend Technologies, a company focused on pushing PHP for mission critical business applications. Rasmus currently works for Yahoo! and is actively involved in the development of PHP.

PHP and RPG have one thing very much in common, when they first came about they were meant to do pretty simple tasks and their names reflected that, Personal Home Page and Report Program Generator. As the years went on, both languages evolved, with RPG and PHP gaining various built-in functions (BIFs), new programming constructs, XML support, and more.

Zend provides two main components to the i5, the Zend Core and the Zend Platform. The Zend Core provides, among many things, the essentials needed to run PHP on the i5. This includes the PHP runtime, the i5 PHP Toolkit, native DB2 support, automatic security updates, a web-based administration console, and more. The Zend Platform provides addition features to the Core, including run-time code optimization, dynamic content caching, PHP/Java integration, and more.

In this article I will begin by giving an overview of the Zend Core installation. Next I will explain what the i5 PHP API Toolkit is and conclude by going through an example of calling an RPG program through PHP.

Installation

The Zend Core makes the installation of PHP on the i5 painless. To start off, create a SAVF in QGPL under the name ZCOREPROD. Then download the Zend Core for the i5/OS to your computer and transfer (via FTP) the included SAVF to your i5. There are numerous open source FTP applications available online, FileZilla is one example. Remember to do a binary FTP upload. Once uploaded, perform a RSTLICPGM command to start the installation, i.e.:

Code:
RSTLICPGM LICPGM(1ZCORE5) DEV(*SAVF) SAVF(QGPL/ZCOREPROD)  

Once the installation completes, you can test everything went OK by pointing your browser to: http://:8000/ZendCore/. This should take you to the web-based administration console for the Zend Core. More information on the installation can be found in the Zend Core for the i5/OS manual and i5php.net. You should now be able to put your scripts in /www/zendcore/htdocs/ and access the files through http://:8000/.

Zend also provides the Zend Studio for the i5/OS, a Java based IDE to assist in the development of PHP applications. IBM and Zend are currently working on the Eclipse PHP IDE project, with version 1.0 set to be released December 2006. For the purposes of this article, I’ll be using WDSC to work with the i5.

i5 PHP API Toolkit

The i5 PHP API Toolkit (iPAT) is an extension built into the Zend Core, giving PHP developers easy access to their i5, natively though PHP. The toolkit is broken apart into seven parts; these include Connection Management, CL Commands, Program Calls, Data Retrieval, Native File Access, System Values and Data Areas. All functions in iPAT begin with ‘i5_’ to ensure no namespace problems come about. The figure below shows the iPAT organizational layout, along with the associated functions.

i5 PHP API Toolkit

Calling RPG/CL program from PHP

The lifecycle of a PHP script calling an RPG/CL program has four main steps, these are connect, prepare, execute and close. A connection first needs to be made to the i5, this is done by using the i5_connect function, and passing in as parameters the i5 IP address, a username and password. The PHP code below shows this:

Code:
$conn = i5_connect("localhost", "gpapayia", "secret");

if (!$conn) {
    throw_error("i5_connect");
    exit();
}

If the connection returns false, then we know something went wrong. I created a function called throw_error, which takes as input a function name and outputs the error number and associated message from the last executed command. The PHP code below shows this function:

Code:
function throw_error($func) {
	echo "Error in function: ".$func." --- ";
	echo "Error Number: ".i5_errno()." --- ";
	echo "Error Message: ".i5_errormsg()."<br>";
}

Next, the program in question needs to be loaded into memory and prepared to be run. This is done by executing the i5_program_prepare function and passing in as parameters the name of the i5 program and a description of the inputs expected by the RPG code. Before I continue to explain this, I’ll introduce the RPG program I plan on using. For the purposes of this article, the example code I made is simple and serves only as illustration as to what can be done. The program takes as input a product id, a store location, and a price. The program updates the price by adding 10.99 and finishes. The RPG code below shows the stored procedure:

Code:
     C     *ENTRY        PLIST
     C                   PARM                    prod_id           7
     C                   PARM                    store_loc        10
     C                   PARM                    price             5 2
      /FREE
       price = price + 10.99;
       *INLR = *ON;
      /END-FRE

Now back to the PHP coding, once the connection is made to the i5, we need to load the given RPG program into memory and get it ready to be executed. This is done by using the i5_program_prepare function, and passing in as parameters the name of the RPG program and a description of the inputs expected. Describing the input variables may seem complicated at first glance, but it’s really is quite intuitive and straight forward. Each input variable is enclosed in an associative array by specifying the Name of the input, the IO being performed, the variable Type being passed in, and finally the Length. The PHP code below shows how this would be done. Notice how the third input, PRICE, has an IO field of I5_INOUT, since I plan on modifying this value from within the RPG code. There is no real difference between calling an RPG or CL program, just specify the correct program name in i5_program_prepare function and everything else stays the same. Again, after i5_program_prepare is executed, I check to make sure no error occurred.

Code:
$description = array(
    array(
    	"Name"=>"PROD_ID",
    	"IO"=>I5_IN,
    	"Type"=>I5_TYPE_CHAR,
    	"Length"=>"7"
    ),
    array(
    	"Name"=>"STORE_LOC",
    	"IO"=>I5_IN,
    	"Type"=>I5_TYPE_CHAR,
    	"Length"=>"10"
    ),
    array(
    	"Name"=>"PRICE",
    	"IO"=>I5_INOUT,
    	"Type"=>I5_TYPE_PACKED,
    	"Length"=>"5.2"
    ),
);

$pgm = i5_program_prepare("QGPL/GEOPGRM", $description);

if (!$pgm) {
    throw_error("i5_program_prepare");
    exit();
}

Notice the return value from the i5_program_prepare function is stored in the variable $pgm. From this point on, any time I want to refer to my RPG program GEOPGRM, I’ll use the variable $pgm. At this moment, the program is loaded into memory and is ready to be run. To execute the program, all I have to do is call the i5_program_call function and pass as parameters the prepared program ($pgm), my input parameters and where I want the output parameters to be stored. The PHP code below shows how this would be done. As above, the input and output parameters are stored in associative arrays. Notice in the $paramOut array, I specified for each given input to the RPG program, the variable names I want to refer to after the i5_program_call completes. For PRICE, I coded in AMOUNT, so after I execute my RPG program, I can get at the PRICE result by using a local PHP variable $AMOUNT. After I execute the RPG program, I check to see if an error occurred, assuming everything went OK, I output the input/output variables from my RPG program using the PHP echo function.

Code:
$parameter = array(
    "PROD_ID"=>"xyz101",
    "STORE_LOC"=>"a1001",
    "PRICE"=>0.00
);

$parmOut = array(
    "PROD_ID"=>"PROD_ID",
    "STORE_LOC"=>"STORE_LOC",
    "PRICE"=>"AMOUNT",
);

$ret = i5_program_call($pgm, $parameter, $parmOut);

if (!$ret) {
    throw_error("i5_program_call");
    exit();
}

echo "Product Id: ".$PROD_ID."<br>";
echo "Store Location: ".$STORE_LOC."<br>";
echo "Price: ".$AMOUNT."<br>";

At this point, my program executed correctly and I am ready to close my program (unload from memory) and close my connection to the i5. This is handled through the functions i5_program_close, taking as a parameter the prepared program, and i5_close, taking as a parameter the connection. The two lines of PHP code to handle this are listed below.

Code:
i5_program_close($pgm);
i5_close($conn);

One reason why PHP has become so popular is that it makes seemingly difficult tasks easy, this in turn frees the programmer to be innovative and spend more time thinking through ideas, rather than coding. Furthermore, resources to assist PHP developers are available all over the internet, including one of the best manuals for any programming language at php.net.

PHP Source Listing
RPG Source Listing

5-second RSS parser w/ simpleXML

Tuesday, September 19th, 2006

During Rasmus’s talk last week at the php|works conference, he showed how easy it is to parse XML in PHP 5, using simpleXML. In his example, he used the Flickr public photo RSS feed, to parse and output. A lot of people don’t know about this feed, which gets updated the moment a new photo gets uploaded. Furthermore, a lot of people upload their personal photos, and make them private after their uploaded. Click here to see it in action. Here are the 2 lines of code:

Code:
<?php
    $url = 'http://www.flickr.com/services/feeds/photos_public.gne';
    foreach(simplexml_load_file($url)->entry as $it) echo $it->content;
?> 

Be sure to mark you photos as private before you upload them..

SemCodeFix: A plugin to display preformatted code in WordPress

Saturday, September 16th, 2006

SemCodeFix is a WordPress plugin I made to display preformatted code correctly. This plugin can display any type of code, html, text, scripts, etc. Using the plugin is easy, just wrap your text in a code tag from within the WordPress editor. Here’s an example of what it would look like. The code below is Python, its a solution to the Eight queens puzzle.

Code:
def n_queens(n, width):
    if n == 0:
        return [[]] # one solution, the empty list
    else:
        return add_queen(n-1, width, n_queens(n-1, width))

def add_queen(new_row, width, previous_solutions):
    solutions = []
    for sol in previous_solutions:
        for new_col in range(width):
            if safe_queen(new_row, new_col, sol):
                solutions.append(sol + [new_col])
    return solutions

def safe_queen(new_row, new_col, sol):
    for row in range(new_row):
        if (sol[row] == new_col or  # same column clash
            sol[row] + row == new_col + new_row or  # diagonal clash
            sol[row] - row == new_col - new_row):   # other diagonal
                return 0
    return 1

for sol in n_queens(8, 8):
   print sol

To activate/use this plugin, do the following:

1. Place the plugin file in the plugin directory of your WordPress installation and activate it.
2. Copy and paste the CSS into your local.css file of your theme’s directory.
3. Depending on your theme, your might want to change the width value in the div.code_child css style.
4. Any code you have, just wrap it in a code tag from within the editor.

When installed, the plugin will override the native code styles of your theme and display output as above.
Download the plugin file
Download the CSS file

Good luck

php|works 2006: Every time Linux boots a penguin gets its wings

Friday, September 15th, 2006

The php|works conference has come to an end, and overall it was a good time.
Here are some links to read more about what happened.

Linux

php|works Toronto Conference 2006: Day 3

Friday, September 15th, 2006

Today was a light day, with only 3 talks and the day ending by 12:30pm. The highways were a mess this morning, I barely made it in time for the first talk. I’ll link to slides as they become available. Here is a quick summary of the presentations I listened in on…

9:00am – 10:00am: PHP-GTK2 by Andrei Zmievski

GTK natively is designed to work with many languages, but PHP? I guess if you really love PHP (and totally hate C), then this is for you, when making desktop application. I’ve havent used PHP-GTK extensively, but I can’t imagine it would scale well for large applications. Regardless, the talk was interesting to see whats new in PHP-GTK2, especially when it was coming from its creator.

Andrei’s Slides

10:15am – 11:15am: Handling Data Without Databases by Elliott White III

For one reason or another, it’s possible that a PHP developer would not have access or want to use a database in their application. This talk covered just that, what could a programmer do when database access is not an option. Eli covered five way to go about this, I’ll cover each briefly..

Filesystem Database

In a Filesystem database, every table and row in your database would become its own directory. This is not a requirement, but thats generally what would happen. With a good directory structure and smart intermediate PHP code to control file access, this could be a decent alternative to standard databases. Eli has examples and code in his slides.

XML

XML is surprisingly similar to a filesystem database, just in this case the directory structure becomes the tags, while the data gets stored directly in the XML. With strong XML support in PHP 5, this could be one of the easier solutions.

PHP Files

This gets into slightly more complex ways of storing data, but can be really effective, especially when using some of the built in capabilities of PHP. If you have an array you want to store in a file or XML, why not just call var_export() and store the resulting string in another PHP file? var_export([array]) takes an array, and returns a string array definition, that could be used to re-generate the array. Just write this string to a PHP file, and include() it as needed.

Serialize/Unserialize

I most commonly use serialization to store objects or data during page transitions. Behyond that, serialization is a great way to store objects in files, databases, etc. Read more about serialization here. I had an interesting problem a little while ago, on how to serialize a class using the __sleep() function.

SQLite

SQLite emulates (mimics) a relational database entirely in memory. All data is stored in a single flat file, which makes backing up and getting at your data easy. These days SQLite is very powerful and gives you a lot of the functionality you would normally expect in a standard relational database. Since this is really just faking a relational database, use it with care and only for small amounts of data.

Eli’s Slides

11:30am – 12:30pm: PHP and Mail: Best Practices by Wez Furlong

This was filled with lots of good information, but brought back bad memories of my battles with email related issues (server configurations, etc). In retrospect, I should have sat in on another talk, since I’ve had so much experience in this area. These days I use the PEAR-Mail package for most of my email related needs.

Wez’s slides

php|works Toronto Conference 2006: Day 2

Thursday, September 14th, 2006

Day 2 of php|works is a wrap, another great day of tutorials and information. Above that, the Holiday Inn is providing great service, refreshments and food. I’ll link to slides below as they become available. A summary of the day and interesting stuff learned follows…

9:00am – 10:00am: Microsoft Platforms for the PHP Developer by Joe Stagner

The day started off with Joe Stagner from Microsoft Canada giving us a one hour talk on PHP and Microsoft. There were a bunch of people there from MS giving away .NET migration books, Visual Studio Express CDs and other propaganda. I guess in the worst case, they would want us to develop/deploy on the Windows platform instead of Linux.

The talk went on about a lot of things including native COM access through PHP, .NET integration with PHP, PHP4Mono and more.

Joe’s slides

10:15am – 11:15am: Cache For Cash by Ilia Alshanetsky

I sat in on two outstanding talks today, the first was this one, and the second was the next (Flash + PHP). So what’s the motivation for caching? Simply put, the PHP engine and MySQL operations present an overhead in parsing, compiling, processing, etc… when displaying a single page. In most cases though, not everything on the page is dynamic, and doesn’t require the PHP engine to be invoked every time.

In Cache for Cash, Ilia went through six ways to cache and how one would go about implementing them. I’ll briefly go through each…

Complete Page Caching

As the subtitle says, this is the process of taking a dynamic page, and storing the generated contents in an HTML file. When the site is loaded, instead of running the PHP script, the server would load the static HTML page.

I have no way of verifying this, but I’m pretty sure Wordpress, Blogger and other large scale hosted blogging engines use complete page caching. This makes sense, since most people won’t make a new post that often, and when they do, the entire page could be re-generated instantly.

Ilia quoted a greater than 40% improvement in latency when caching his pages using the blogging engine Serendipity. Caching could be taken even further, to check the browser encoding header for GZip, and if so, send the GZip’d version of the page, instead of the original. In many cases this could cut down in half the amount of data being transferred over the wire.

Content Pre-generation

Imagine you have an online store front selling 1000 products (0 through 999). Each of these products have a product description page, say by desc.php?id=xxx, the xxx would represent the numbers ranging from 0 through to 999. Since your prices wouldn’t change that often, you could write a script to generate all 1000 pages, and have the application call these pre-generated, cached files. The general theme here is simple: remove PHP from whatever you can. This is what Livedocs does; they improved their latency from 611.2 ms all the way down to 2.37 ms, because they removed both PHP and XSLT from the equation.

The secret here is not to just store the static pages on your normal HTTP server. Since the pages are static, you should use a light weight server, like lighthttpd, which would have a very fast response time. This type of caching doesn’t come without its problems; first off disk space could become an issue through so many files being generated. Furthermore, ext begins to suffer when the file system surpasses a certain number of files. Secondly, you could be easily pre-generating pages which might not ever be used. If you have thousands of pages, your wasting disk space, and before the page is ever used, it might need to be re-generated again.

On-Demand Caching

The idea here is to generate what you need, when you need it. Depending on what you’re doing, this could be a really good option. When I first heard On-Demand Caching, the first thing that came to mind, was MagpieRSS. This package grabs a given RSS feed (or XML) on demand, and gives you the ability to use the results in your application on the fly. If the headers of the given feed indicated that the XML hadn’t changed, then the cached version of the file was used locally for parsing, instead of downloading it all over again.

Ilia gave a cool idea on how to implement On-Demand Caching: Have all pages initially display a static HTML page. The short PHP code that would load this static page, would first check if the given HTML had been updated. If so, the script would throw a 404 error, instantly sending the user to the 404 page. There is nothing stopping you from creating a custom PHP 404 page, that looks at the URL it came from, and auto-generates the updated (new) content for that page. The new page would not only be displayed to the user, but also cached for future requests. The only issue here is that your logs might get cluttered with false error messages.

Partial Page Caching

The idea here is to have a light weight http server providing all static pages, in conjunction with dynamically generated content. Full caching is not possible in this case, since the pages have dynamic content, that can’t be avoided. To improve the latency of the dynamic content though, an APC style middleware should be used. I’ve gone through APC briefly in the summary of day 1, but here’s a bit more. With APC you have the ability to manually put data into shared memory. There are basically three functions you need to know:

apc_store([key],[var],[time till expiry]); — place data (var) into memory using a [key] and have it expire via the third parameter
apc_delete([key]); — remove the data associated with [key] from dynamic memory
[var] = apc_fetch([key]); — grab data from shared memory using a [key].

SQL Caching

Ilia made an interesting statement at this point, he said many application work with a database, but few do it efficiently. We learned about three types of SQL caching:

DB SQL caching: Say your blog has 10 commonly used search terms. Rather than having your site go through these expensive searches each time, you could cache them in a separate SQL table. This makes sense, since a single table read in MySQL is very fast, and the results would come back almost instantly.

On-Disk SQL Caching: Using the example above, rather than storing the search results in a single db table, you could store the results in a file. This has a similar idea to page caching.

In-Memory SQL caching: This is the same idea as above, just you would be storing SQL data in memory using APC or SHMOP. APC is meant for PHP Opcode caching, but there’s nothing stopping your from storing SQL results data instead.

Browser Caching

This type of caching virtually reduces the data sent from the server to 0. The problem here, is that browser caching is not guaranteed and every browser implements this differently. There are three ways to implement browser caching from a PHP application:

header(”Expires:”…. This tells the browser to hold this page till a certain time
header(”Last-Modified:”…. This puts all the control in the browser, as to when to re-fetch the page
header(”Etag:”…. This is the most reliable method, by sending a unique identifier check-sum to the browser, notifying it, that the page has changed

Ilia’s slides

11:30am – 12:30pm: Flash + PHP: an Alternative to AJAX by Christian Wenz

Christian is a great presenter. He has a distinct style, were he likes to talk and show examples rather than follow/read off slides. He tries to make the talks seem like he’s coming up ideas on the fly, but its easy to see he’s thought through everything he wanted to say.

This talk focused on how a PHP programmer can use Flash to easily make rich UI applications. The presentation covered an introduction to Flash, how it integrates with PHP, demo applications, and finally Macromedia Flex. I’ll just cover a few highlights.

To begin with, Flash is semi-open standard, along those lines third part tools exist for developing Flash applications, but their always behind the Adobe developed Flash development studio. The Flash scripting language is called Action Script, similar to Dojo style JavaScript, Action Script is an ECMA approved Script Standard and in recent years has really begun to gain a lot of power and functionality.

An interesting development coming up is Flash Light. It appears this is going to be a light weight version of Flash, which would be used to develop application for mobile devices. These application would run standalone on a phones OS, outside of any type of browser.

Flash and PHP

A developer has many options to connect with PHP when creating Flash applications. The original way was to use the Action Script functions loadVariable and getURL. From here loadVars came about, which was an OOP version of loadVariable, now allowing for a callback function to handle results.

Probably the most interesting way to connect with backend logic is to use Flash’s inherit ability to work with Web Services (SOA). With SOA, the developer can create their business logic, wrap it in a WSDL and have a desktop application, web application, Flash app etc. all run off the same code. The world is moving towards SOA, even MS ;)

The most complicated method of connecting with a backend, had to be Flash Remoting. This was some intense binary data transmission method, based off of AMF (Action Message Format). The Macromedia supplied version of AMF is very expensive, but luckily there are open source alternatives including AMFPHP and PHPObject.

Christian’s slides

1:30pm – 2:30pm: Derick’s Ranting Hour by Derick Rethans

This was a light-hearted, open discussion on PHP, by the people who actually develop the language. The slides include funny examples of bug reports, emails and more.

Derick’s Slides

2:45pm – 3:45pm: The State of AOP in PHP by Sebastian Bergmann

In this talk, Sebastian gave an introduction to Aspect Oriented Programming, examples of syntax, theory and how he was going about implementing this in PHP. To get a good understanding of AOP, you’ll need to do some good research.

Sebastian’s Slides

Your Ad Here