ucantblamem

Hi, I’m James Angus. I have a greed for learning, an obsession with all things web; I am in love with standards, accessibility, creating things for use by people and yes, this site was designed on a mac. Read on ยป

Ramblings of a restless mind: April 2008

1st May 2008

Just a short list this month:

Quick and dirty objects in PHP

19th Apr 2008

If you have taken the opportunity to read more than a single post on this blog, it should come as no surprise that my two favourite programming languages are Ruby and JavaScript - almost completely because of the strong object-orientation of the languages. However, PHP is the bread-winner in this family of one and my lust for all things objective - syntactically speaking - has kept my mind busily crafting ways of bending PHP to my will.

One of the (many) reasons I enjoy using these languages is that they both possess the ability to create objects without having to define classes and instantiate them. For instance, consider this regular Ruby object:

class MyClass
	def initialize
		@my_first_var = 'Hello'
		@my_second_var = 'World'
	end
end

my_initialised_object = MyClass.new

Which could more easily be written like so:

{
	:my_first_var => 'Hello',
	:my_second_bar => 'World'
}

This syntax makes it very easy for us to do one-liners like this:

{ :one => 1, :two => 2 }.has_key?(:one)

Now, Ruby bofins will point out that what I just created is actually a Hash - but, a Hash, like everything else in Ruby, is in fact an object and can thus have methods called against them… Let’s move on shall we?

For the fun of it, let’s create those same two (original) objects in JavaScript:

function MyClass() {
	this.my_first_var = 'Hello';
	this.my_second_var = 'World';
}

var my_initialised_object = new MyClass();

And in short-hand form:

{
	my_first_var: 'Hello',
	my_second_var: 'World'
}

These short-hand methods of creating objects come in handy quite regularly in both languages and there has been many times when I have cursed PHP for it’s lack of a similar syntactic-sugar. For illustrative purposes, consider the following line of ruby-code:

"A simple string".apply_formatting({ :transform_to => 'uppercase', :limit_words_to => 4 })

Short, sweet, clean and self-documenting - smells like beautiful code to me.

While working on Musicadium.com this past week I realised that PHP does provide a way of creating short-hand objects and the solution is actually something I have written about before on this very blog. Sadly, even after writing that article I failed to connect the dots between an age old PHP feature and the problem I’m talking about here.

Before I unveil this little gem though, let’s create a regular object in PHP, to continue the nice little theme I have going:

class MyClass {
	var $my_first_var = 'Hello';
	var $my_second_var = 'Hello';
}

$MyClass = new MyClass;

Now, watch closely or you’ll miss the silver-bullet:

$my_initialised_object = (object) array('my_first_var' => 'Hello', 'my_second_var' => 'World');

My friend; the cast. It is a shame that I should have to resort to casting an array - which is a little slow from a performance perspective - but it is a necessary sacrifice for my coding sanity.

Casting has once again come to the rescue and made my daily development just that little bit sweeter. Unfortunately, PHP still doesn’t allow me to perform methods on that object - as with the Ruby example - but it’s a small step closer to my object-oriented dream.

Match maker, match maker…

10th Apr 2008

Of the 95 string functions available in PHP, not one gives you the convenience of loosely matching two strings. What do I mean by that? Well, you and I could easily discern that the phrase “funding and charters” is the same as “Funding & Charters“, however a computer would not consider these the same - certainly not using PHP as the processing tool anyway.

Recently I finished the build of a Training Package Issues Register for a government organisation. This Issues Register is setup so that the client can put an entire Training Package online (equivalent to 4000 pages in a *.doc file) and have registered members give feedback about each of the Qualifications, Units, Skill sets and various Discussion Papers.

Previous to this online system, the client had been gathering feedback manually and collating it into spreadsheets, which ultimately they wanted to import into the online system. The feedback table - in our database - was recording the “type” of feedback using a single character; “u” for feedback that has been made against a Unit, “q” for qualifications, etc, etc… The clients’ spreadsheet had a method of identifying the feedback type as well, however the values were not uniform and some examples included “Core Units”, “Training package unit”, “Qual”, etc…

This meant that we had to come up with a method of more loosely comparing strings, so that we could get “Core units” and “Training package unit” to be recognised as a “Unit” and ultimately store a “u” in our feedback table.

After some brainstorming and discussion with the team, we concluded that this was a job for SQL’s full-text search capabilities. In a nutshell - using full-text search - we asked the system to return the most likely matches for a given string and order them by “relevance” (how similar a result is to the original string).

We decided that when doing an import we would create a temporary (in memory) table of the different feedback types and then performing a full-text search against it to find the most relevant type we have on record. While this form of matching isn’t an exact science, the likelihood of a mismatch is quite low and we already had the functionality to allow the administrator to repair these edge-cases manually.

It could be argued that we are making a redundant call to the database, but considering that these imports are rarely performed and only ever by a single user, we decided that the convenience outweighed any possible performance issues.

In anycase, the point remains that while PHP isn’t very intelligent when it comes to matching natural language strings, SQL is and it’s definitely something that I recommend every developer make a place for in your mental toolkit for when you next encounter a problem similar to ours.