PHP class for Google Geocoder API

For a project I’ve been working on, I needed to access Google’s Geocoder API. I search for names (schools in this case), and return as much info as I can that Google has about it.

I’ve posted the class up on Github, it’s straightforward, and might help some people out:

http://github.com/nshahzad/Google-Geocoder

The usage is in the readme/displayed right on the github page. It uses cURL and JSON to keep the traffic transfered low. That also means you need the json_decode() function, which is in PHP 5.2 and up.

Happy 4th!

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

Getting a revision number from git

I needed an atomic revision number from git, so I decided to use ‘git bisect’ for now. You’ll need the commit hash for the very first commit in the repository:

[bash]
> git bisect start
> git bisect bad HEAD
> git bisect good [hash]
Bisecting: 451 revisions left to test after this (roughly 9 steps)
[bc650f51650c208cf96eea6324dfb6564c86d099] Maintenance options
> git bisect reset
[/bash]

Then you can parse that. Works good enough for me! Of course, it’ll be good if you can tag that very first commit, you can use that as the reference point.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

Building php-fpm against Ubuntu PHP Packages

This is how I’ve been building php-fpm against the Debian PHP packages. It’ll be useful for when Ubuntu 10.04 (Lucid Lynx) Comes out with PHP 5.3. I do this from my home directory. It will download the package souce from Ubuntu, then compile php-fpm standalone against that.

[bash]
sudo apt-get install php5-cli php5-cgi php5-common \
php5-curl php5-dev php5-gd php5-mcrypt \
php5-memcache php5-mysql php5-suhosin

# Get from the Debian repo
sudo apt-get build-dep php5-common
sudo apt-get -b source php5-common

# Change this to the PHP version being used!
# Look on http://launchpad.net/php-fpm/master to match it
export PHP_VER=5.2.10
wget "http://launchpad.net/php-fpm/master/0.6/+download/php-fpm-0.6-$PHP_VER.tar.gz"
tar -zxvf "php-fpm-0.6-$PHP_VER.tar.gz"
cd "php-fpm-0.6-$PHP_VER"
mkdir fpm-build && cd fpm-build
sudo ../configure –srcdir=../ \
–with-php-src="../../php5-5.2.10.dfsg.1" \
–with-php-build="../../php5-5.2.10.dfsg.1/cgi-build" \
–with-fpm-conf="/etc/php5/fpm/php-fpm.conf" \
–with-libevent="/usr/lib"
sudo make
sudo make install
sudo update-rc.d php-fpm defaults
[/bash]

Resulting in:

[bash]
Installing PHP FPM binary: /usr/local/bin/php-fpm
Installing PHP FPM config: /etc/php5/fpm/php-fpm.conf
Installing PHP FPM man page: /usr/local/man/man1/php-fpm.1
Installing PHP FPM init script: /etc/init.d/php-fpm

*** FPM Installation complete. ***

run:
`update-rc.d php-fpm defaults; invoke-rc.d php-fpm start`
[/bash]

Then, configure the php-fpm file. That should be it :)

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

Host move complete…

Completed my long move today over to Linode from Slicehost. A few reasons for the switch – the main two being the price (I’m now on a Linode 560, which is 560mb of RAM, vs the 512 at Slicehost for the same price). They also give a 10% discount for pre-paying for a year, or 15% for two years. But you’re not stuck in a contract. Sweet deal there. The other reason was that Linode doesn’t force you to go on x64, so you’re not wasting memory needlessly to the OS. The box “feels” faster, probably because I have a lot more free RAM since I chose to go on 32bit. No swap usage so far (alot of room available), with identical set ups. My slice was constantly using swap. My ping times are also certainly lower. So far so good. I got to also chose the data center, over at The Planet in Dallas. The Linode control panel is also “meatier”, compared to the Slicehost manager. Linode gives you 24-hour and 30-day usage graphs, with averages and stats on CPU, network, and disk IO. Really useful information. The only downside is that the image backups at Linode are in “beta”, but doesn’t matter so much to be since I use an outside backup service anyway.

I also did a fresh upgrade to Ubuntu 9.10 “Karmic Koala”, which is what I was waiting on to make the switch. Went very smoothly; I stayed with nginx, except this time, instead of using the php-fcgi, I decided to try out the php-fpm route. It was a bit of a hassle, and took the better part of a day, though I got it working in the end. But that’s because it was my first time doing it. I will have a post on that soon. Basically, I installed the Ubuntu 5.2.10 packages, and then compiled php-fpm against that source, which fixed a few issues I was having with configs not getting picked up when I compiled it against the vanilla PHP source. So far so good, running with APC and memcache going.

I think I will next try to compile PHP 5.3 from source, and add PHP-FPM into it, though I feel like waiting for a package. Perhaps a project for next weekend, but definitely something to try on a virtual machine first. I was reading a few bugs that APC was a bit wonky on 5.3, so I might wait until 5.3.1, and that Suhosin is also a bit sketch. Though, it might be some good motivation to try out XCache. To be honest, I was a bit disappointed that 5.3 wasn’t included by default in 9.10. I was trying to find out when it might be, but I think it could be a while. At least this time around, I took real detailed notes on what I did, from start to finish. I’m not so afraid of compiling this time around. For instance, nginx, I compared the layout of the Ubuntu repository copy, and mimicked that with –prefix and the –sbin-path configure options. It’s just convenient having the “sudo apt-get upgrade” command. Ubuntu also made it real easy in terms of dependencies. I remember a few years ago trying to compile stuff, and it was always a nightmare. I think that’s what scared me away from it, but it was pretty painless this time around.

Other updates – phpVMS, a lot of progress, thanks to everyone for helping test, fixing alot of bugs. Made alot of core changes too, which I’ll detail in the release post – hopefully in a few weeks. Same with vaCentral, I’m trying to get them both out at the same time. But thanks to everyone testing, I’ve been able to nail a lot of bugs. It’s looking much better than it did a few weeks ago.

Anyway, I’m fried. Time for a break. And, Happy Halloween!

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

Function Parameter Hell

Everyone’s used those functions with an obscene number of parameters. And everyone’s created those functions too (big time guilty here).
Like this is a function I wrote for vaCentral to process any images you upload for your airline (logo, gallery, etc)

[php]
function process_file_upload($file, $slug, $title, $ext=’PNG’, $full_size=300, $small_size=100)
{

}
[/php]

Now that’s just a mess. Taking a hint from Javascript and jQuery, we can instead use arrays to pass in parameters, making it sane, and more importantly, readable. So it will look something like this:

[php]
$options = array (
‘file’=>$this->params['form'][$image],
‘slug’=>$folder,
‘title’=>$image,
‘ext’=>$ext,
‘full_size’=>$large_size,
‘small_size’=>$this->small_size
);

$this->process_image_upload($options);
[/php]

Alright, that sounds better. And looks much better, and I can actually understand what’s going on. But how will we work with this? As you’ve probably noticed, default parameters are gone. Here’s the code:

[php]
// Setup our options for what we want to pass
$options = array(
‘parameter1′=>’apples’,
‘parameter3′=>’grapes’,
);

some_function($options);

function some_function($options)
{
// Now these are the defaults
$defaults = array(
‘parameter1′=>’oranges’,
‘parameter2′=>’watermelons’,
‘parameter3′=>’grapefruit’,
‘parameter4′=>”
);

/* Now we merge the two arrays, except the $options
array takes precedence */
$options = array_merge($defaults, $options);

/* extract() creates a variable with every key from the array
so we can use that variable directly, this is optional */
extract($options);

// So now we can use the variables directly
echo $parameter1; // This will echo "apples"
echo $parameter2; // This will echo "watermelons"

/* Suppose parameter4 has to be set, so we will trigger an error
You can use throw as well if it’s in a try/catch block */
if($parameter4 == ”)
{
trigger_error(‘Parameter 4 must be set to "this value" or "that value"’, E_USER_WARNING);
}

/* Or, if you assume that the $defaults set with ” are mandatory to fill out,
you can use this code */
foreach($defaults as $name=>$value)
{
if($values == ” && $options[$name] == ” || !isset($options[$name]))
{
trigger_error("{$name} is blank, must have a value", E_USER_WARNING);
}
}
}
[/php]

Now obviously this is a little more involving, but it’s not too bad, and in my opinion, it’s well worth the extra effort needed. My tipping point is functions with more than 3 parameters will get array’d options. This also requires documentation, but I don’t think that’s such a bad thing (your sanity will thank you later). You can also peek into the function’s source code to see the parameters. But this also gives you a bit more control over error messages as well, with the trigger_error, so there’s no difference from how PHP natively reports it.

Also, another advantage is adding and removing parameters. You don’t need to reorder or completely destroy things, when in the future you decide to add or remove a parameter, which makes it real handy for API type functions. Debugging and logging can also be easier, since you can dump the entire parameters array in one swoop, without having to output every single variable, one at a time. The only drawback is the lack of restrictions on a blank value, but since there is a way around it, and you’re forced to check it, IMO that’s an advantage in the end, especially since my motto is to never trust any data coming into the system, especially in an API.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

A better way for nginx PHP config

Doing some reconfiguration on my webserver (nginx) to make it easier to administer. My first goal was to get rid of this nastiness:

[bash]
server {

location ~ \.php$ {
include /etc/nginx/conf/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/path/to/$fastcgi_script_name;
}
}
[/bash]

It’s too verbose to copy/paste into each virtual host file. Instead, you can just combine the file into the /etc/nginx/conf/fastcgi_params file. I renamed it to php_params, and this is what it’s got:

[bash]
location ~ \.php(.*)$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;

fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with –enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
}
[/bash]

Now I don’t have to change it everywhere. So, instead, now I do:

[bash]
server {

# Include the PHP Fast-CGI Params
include /etc/nginx/conf/php_params;
}
[/bash]

Bam! 6 lines down to one, and much easier to administer. I like, I like.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

PHP Resources

I put a list together for a friend of some good PHP resources, thought I’d stick it up here as well:

Of course, the best resource, the official docs:
http://www.php.net

Another great (official) place:
http://talks.php.net/

The talks are by the creators of PHP. Any talks by Rasmus Lerfdorf are excellent, he stresses simplicity over complexity. He’s also the creator of PHP. Derick Rethans is also an excellent presenter, he focuses a lot on security and debugging. Definitely watch the presentations in the “Security” section of the talks, but overall, any talk in there has information you can use to your advantage.

Other sites:
http://www.smashingmagazine.com/2009/03/24/10-useful-php-tips-revisited/
http://php.about.com/od/advancedphp/Advanced_PHP.htm

Sitepoint is where I first started learning HTML and CSS many years ago:
http://www.sitepoint.com/subcat/php-tutorials

MVC tutorials (how apps should be coded; obviously there’s some contention between OO and procedural styles, but you need knowledge of both to be able to make an educated judgment about what a good balance between the two is)
http://www.phpro.org/tutorials/Model-View-Controller-MVC.html
Good to go through to understand MVC completely

CakePHP has a good introduction:
http://book.cakephp.org/view/10/Understanding-Model-View-Controller

Which brings me to CakePHP itself. It’s an excellent MVC framework; after trying out CodeIgniter, Zend, Yii, Kohana, I’ve settled on Cake.
http://cakephp.org/

SQL resources – the best is the manual. Learning the concepts behind joins is essential and important. A good tutorial:
http://www.codinghorror.com/blog/archives/000976.html

Also database design:
http://www.simple-talk.com/sql/database-administration/ten-common-database-design-mistakes/
http://woork.blogspot.com/2008/09/10-useful-articles-about-database.html

Following that up are good ORM, which you may want to use as your database layer. CakePHP has ORM built-in, but sometimes all you need is just a DB layer.
http://www.doctrine-project.org/

For conventions, I tend to follow the CakePHP model (since that’s the framework I use the most):
http://book.cakephp.org/view/24/Model-and-Database-Conventions
http://bakery.cakephp.org/articles/view/database-design-and-cakephp
http://book.cakephp.org/view/22/CakePHP-Conventions

And then rounding it out, some general knowledge information:
http://articles.sitepoint.com/category/html
http://articles.sitepoint.com/category/javascript
http://articles.sitepoint.com/category/cssh
http://www.jquery.com

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

Busy busy

Been a busy few months with work, phpVMS, and vaCentral. I can’t believe my last post was in July. Time really flies!! But anyway, I’m hoping to wrap up the last two projects by the end of October. Right now, there’s 15 airlines participating in testing for vaCentral, and some impressive stats in the last two months or so I’ve been testing:

  • 5,055 PIREPs submitted, with an average of 20-30 per day
  • Over 22,000 flight hours recorded
  • 15 airlines right now, with 705 total pilots

If that’s any indication, I think vaCentral will be a huge success. I’ve been building it on CakePHP, which has made it real easy for development. Doing some tweaks to ranking and stats, but otherwise, almost there.

In other news, I think I’ll be transferring everything over to fivedev.net, as a huge portfolio/blog type of thing. Might be better. I’m still trying to find an alternative to WordPress, but haven’t had much luck. I have a couple of PHP articles I’ve wanted to publish, including one of writing more “portable” PHP, with stuff I learned from developing on phpVMS and other projects, but just haven’t had the time to complete it. Soon, hopefully.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

CakePHP Models – multiple columns to the same table

This one took me a few to figure out. On VACentral, there are schedules, which have an arrival and departure point. These points are all stored in one table, so one row in schedule refers to multiple entries in the airports table. It looks something like (ok, not something like, but exactly):

[code]
Schedules:
id | departure_icao | arrival_icao

Airports
id | icao
[/code]

So two ICAO columns in routes map to one same column in airports. The ICAO is a unique 4 character identifier, which is assigned to an airport. It’s quite simple actually, but took me a while to figure it it. First the Airports model:

[php]
class Airport extends AppModel
{
public $name = ‘Airport’;
public $primaryKey = ‘id’;
public $actAs = array(‘Containable’);
}
[/php]

And then our Schedules model:

[php]
class Schedule extends AppModel
{
public $name = ‘Schedule’;
public $primaryKey = ‘id’;
public $actsAs = array(‘Containable’);

public $belongsTo = array(
‘DepartureAirport’ => array(
‘className’ => ‘Airport’,
‘foreignKey’ => false,
‘conditions’ => ‘DepartureAirport.icao = Schedule.departure_icao’,
‘fields’ => ”,
‘order’ => ”
),

‘ArrivalAirport’ => array(
‘className’ => ‘Airport’,
‘foreignKey’ => false,
‘conditions’ => ‘ArrivalAirport.icao = Schedule.arrival_icao’,
‘fields’ => ”,
‘order’ => ”
)
);
}
[/php]

So we used the $belongTo relationship, and we will define two relationships – “DepartureAirport” and “ArrivalAirport”. We also select the class we will use (which IMO, should really be called “modelName” or “useModel”, that really tripped me up, but I digress). Next, we define the conditions – we’ll use the relationship name (DepartureAirport or ArrivalAirport), and the column name, along with the column name on the current table it should join on. And that’s pretty much it. You don’t really need a relationship on the “receiving” end (the Airports table), unless you will be querying airports, and finding out what schedules go there. I’ll leave that upto you ;)

And then for the query itself:

[php]
$this->Schedule->contain(‘DepartureAirport’, ‘ArrivalAirport’);
$schedule = $this->Schedule->find(‘first’);

// Our Airport specific data will be contained in:
$schedule['DepartureAirport']
$schedule['ArrivalAirport']
[/php]

Which will now return something like (etc fields ommitted):

[code]
Array
(
[Schedule] => Array
(
[schedule_id] => 4178
[airline_id] => 2
[code] => AEA
[flightnum] => 6371
[depicao] => CYUL
[arricao] => KJFK
)

[DepartureAirport] => Array
(
[airport_id] => 597
[iata] => YUL
[icao] => CYUL
[name] => Montreal / Pierre Elliot Trudeau International Airport, Quebec
[timezone] => US/Eastern
[location] => Montreal QC Canada
[lat] => 45.470556
[lng] => -73.740833
)

[ArrivalAirport] => Array
(
[airport_id] => 268
[iata] => JFK
[icao] => KJFK
[name] => JFK Airport
[timezone] => US/Eastern
[location] => New York-Kennedy NY
[lat] => 40.6398262
[lng] => -73.7787443
)

)
[/code]

Note how it's using the Containable behavior; this is so it doesn't pull every relationship you've defined with that table (the schedules table above has many more relationships, but for brevity, I only pulled the relevant ones). Not specifying Containable() is REALLY expensive, especially when you don't need all those relationships to be included in every time! To speed it up even more, you should specify the actual field names to pull (the SQL * operator is expensive).

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz

ezDB and PHP 5.3

As-per Justin’s request, I’ve renamed by fork of ezSQL to ezDB. I’ve updated the github links, it’s now:

http://github.com/nshahzad/ezdb/

This will include changes to the class names, to keep it all even (ezSQL to ezDB). I’m working on APC caching right now, since that’s what I’m using on current project.

PHP 5.3 was also released today! This is an exciting release – with the addition of namespaces and __callStatic(), the static DB class will be much easier to work with (instead of replicating every function). I will be finishing up the 5.2 release first, and then subsequent releases and features, I think I will be posting to the PHP 5.3 release only, unless there’s demand to back-port it all.

I’ll also be implementing some features from CakePHP’s ORM, such as “findBy{ColumnName}({tablename})”, and other simple lookups. I’ve been using Cake alot too, and it’s a great framework.
Cheers!

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • HackerNews
  • Netvibes
  • Reddit
  • StumbleUpon
  • Twitter
  • Yahoo! Buzz