May 27, 2008

Orlando PHP Meetup

Kevin Hallmark @ 2:50 pm —

Next Tuesday at the Bonnier Corporation offices is the Orlando PHP Meetup. We’re going to be doing a code-shootout comparing Zend Framework, CakePHP, CodeIgniter, and Symfony.

I’m going to representing Zend Framework.

The goal is for each developer to create the same application using each framework. Each developer is already up to speed with their respective framework, to eliminate the learning curve for each framework.

Which framework will reign supreme? Show up and find out!

May 20, 2008

HTTP Error Codes

Kevin Hallmark @ 2:08 pm —

My co-worker posted a great summary of common HTTP error codes that require a custom page handler. Many times, you’ll find sites that don’t actually deliver the correct error codes. This list helps you make sure to handle the different conditions properly.

Check it out here

May 15, 2008

Zend Framework – An Example Model

Kevin Hallmark @ 3:48 pm —

Here is a little advice for people who want some guidance on creating their a model layer:

NOTE: This is merely a simple example, for guidance only. YMMV. There are a million different ways to do this kind of thing, this is merely one I have found effective.

In my apps, I generally create a BaseModel class, from which all others inherit. In this class, I’ll define a basic API that I want all models to subscribe to. This is usually something like __get, __set, setDataFromArray, validate (verify data is correct), filter (filter input data), save and other common methods.

This setup lets you change the backend storage mechanism easily. If all your model objects use the same API, you can change the underlying storage code of all your models simultaneously and your app is none-the-wiser.

An example:

Say I begin by using an array to store my data. Suddenly, I realize I want to store my data inside a database. I can change all the methods in my model to set data to a database object. Later in the project, I decide that XML would be a better choice. I can change my methods to write to an XML data file, and once again I don’t have to change my application code.

You can implement custom behavior by overriding methods and using the ‘parent’ keyword to call the BaseModel method implementation.

In most apps these days, my BaseModel class directly extends Zend_Db_Table_Row. Extending Zend_Db_Table_Row allows my model objects, with all their custom functionality, to be returned directly by Zend_Db_Table function calls. Creating lists is much faster when you don’t have to iterate the result set a second time to create model objects from them.

I usually won’t override the methods I want to use from Zend_Db_Table_Row (__get, __set, setDataFromArray). If I needed to change my storage engine I would implement these methods in my BaseModel to access the new data storage mechanism.

In each of my BaseModel subclasses, I’ll usually add some static getter methods.

For example:

Class User extends BaseModel {
Public static function getUser($user_id = null) {
//return a setup model object
$table = new users();//where users is your table class
If($user_id === null) {
$return = $table->createRow();
} else {
//get row from db

Return $return;

This function would return the model object for ‘$user_id’, or an empty object if null. You can call this method with

Each model then has a single point of origin. If I decide to change my implementation, I can be assured that “User::getUser” always will give me a fully qualified User object.

You can also create similar functions the will return a list of rows.

Hope this small bit of advice helps get your started.

May 9, 2008

The Password Anti-Pattern

Kevin Hallmark @ 11:55 am —

My friend at work sent me this interesting article about the password anti-pattern and I thought I would share it with you.

It’s called the password anti-pattern and it’s on Jeremy Keith’s blog.

Basically, new application frameworks like the Facebook api have created some unpleasant trends. The most significant trend is asking a user to enter their login and password to a site in order to access the user data. Jeremy contends that in doing so, we’re causing user’s to give away their login and password without thinking about it.

I urge everyone to not implement this feature into their applications. While your application may not be malicious, and your favorite application might not be malicious, someone else’s could be. We need to prevent the egregious breach of good security practice from becoming common place. As Jeremy mentions, there are alternatives out there. Google and Flick both have API’s that allow a user to authenticate without having them send you their login credentials. If you have control of the web services you are consuming with your application, you should consider implementing the same kind thing. In the long run, it will take longer. I think the advantages will outweigh the disadvantages in the end.

I pledge not to implement a feature like that on any site, even if it costs me a contract. Short term monetary gain is not worth perpetuating poor design to all internet users.