June 7, 2011

LBHToolkit: Using the PHP5 vCard Generator

Kevin Hallmark @ 9:30 pm —

I was having a lot of trouble finding a suitable vCard generator for one of my personal projects last year, so I whipped up this little class to let you quickly generate a vCard in an object oriented way.

The example below can help you use the class. It’s actually really easy. Just instantiate the class, set properties to it with standard object notation, and then call “Generator::create()”. A list of all the fields can be found in LBHToolkit/vCard/Generator.php

LBHToolkit vCard Example

<?php
// Include the class
require("library/LBHToolkit/vCard/Generator.php");

$vcard = new LBHToolkit_vCard_Generator();

// Name, requires a little knowledge of vCard.
$vcard->formatted_name = "Kevin Hallmark";
$vard->name = 'Hallmark,Kevin';

//Company nae
$vcard->company = "Little Black Hat";

// Assign an address
$vcard->work_address = "123 Fake St";
$vcard->work_city = 'Orlando';
$vcard->work_state = 'FL';
$vcard->work_zip = "12345";

$vcard->work_phone = '555-555-5555';

$vcard->note = "Kevin is a nice guy.";

 

echo $vcard->create();

December 10, 2010

PHP is falling apart (or Why we need ‘finally’)

Kevin Hallmark @ 11:58 am —

PHP is crumbling.

PHP 6 was delayed for years and now sits abandoned as they restart the effort. In the meantime, a bunch of features are being backported to PHP5.x branches. Each new 5.x release has more features from what would have been PHP 6. PHP is stagnating.

The PHP core team has fallen apart. There is no leadership. There is no guidance. There is no logic. There is just a cobbled together release of miscellaneous features that are somebody’s baby.

For example, ‘goto’.

‘Goto’ should not be implemented in any modern language, period. It’s not needed. Yet, PHP chose to implement this in version 5.3! The reasons for adding this were dubious at best, showing a lack of language design skills. You can read all about my opinion on goto here: http://www.littleblackhat.com/blog/2009/11/php-5-3-and-goto/

I recently found this little gem on the php website: http://bugs.php.net/bug.php?id=32100 (thanks @lesmothian).

The best (and only) comment we get about why there is no ‘finally’ block is “We’ve had long discussions and came to the only conclusion that we don’t need that, for more search the mailing list archieves(sic).” Of course, that conversation can’t be found in the list archives. Does that matter? Of course not.

Finally is part of many modern programming languages: Java, Javascript, C#, Ruby, Python, Objective C, Perl, VB.net… the list goes on. Many of these languages and their designers abhor ‘goto’ and praise ‘finally’.

The use cases for finally assure proper memory management and resource deallocation. Without it, the chance for a mistake in control structure flow increases significantly. Additionally, unless I reraise the exception, it short circuits my app wide exception handling code. Reraising deletes runtime information about the source of the error.

Finally results in cleaner more reliable code. It should be implemented in PHP.

This essay only touches on the idiotic decisions of the PHP team. First ‘goto’, now ‘finally’. Suffice to say, I am getting less and less attached to PHP by the day. I hope that one day the php team gets some leadership again.

February 12, 2009

Getting xDebug Working on Mac OS X with MacPorts

Kevin Hallmark @ 3:25 pm —

xdebug is a powerful PHP debugging tool. With xdebug you can get all sorts of debugging out, stack traces, and memory usage (as well as delta). It also gives you classic code-stepping tools and breakpoint. Finally, you can debug your PHP applications! Getting it working on Mac OS X has been a bit confusing, but this how to guide will give you all the tools you need!

Before we proceed, you have MacPorts installed right?

So how do we go about getting xdebug? First, install xdebug:

sudo port install php5-xdebug

Next enable xdebug. All this goes in your php.ini

; NOTE: This line adds the xdebug extension. The macports install will give you the path, 
; or may even add this automatically. Be smart, look for a similar line in your config first.
; (Edit: 06/22/2012)
zend_extension="/opt/local/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so"

; General config
;Dumps local variables on exception
xdebug.show_local_vars=On
;Dump server variables
xdebug.dump.SERVER=*
;Dump global variables
xdebug.dump_globals=On
xdebug.collect_params=4;

; Tracing
xdebug.auto_trace=On
xdebug.trace_output_dir= /opt/local/php_traces/
xdebug.show_mem_delta=On
xdebug.collect_return=On

; Profiler
xdebug.profiler_enable=1
xdebug.profiler_output_dir=/opt/local/php_traces

; Debugging. You might need to specify your host with some additional options
xdebug.remote_enable=1

For viewing profile output:
http://www.maccallgrind.com/

You will use this program to open the cachegrind.out files in /opt/local/php_trace

For using the debugger:
http://www.bluestatic.org/software/macgdbp/

Just put “XDEBUG_SESSION_START=session_name” in your query string. Session_name can be any alphanumeric string.

You can set a breakpoint with: xdebug_break()

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 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.