PHP ain’t that funny after all

I don’t like PHP. I use it on the web because it’s everywhere and you can find a busload of code to do pretty much whatever you want. But I really dislike how it’s designed. It’s inconsistent, you’ll never know what might happen when you call that new function you just found.

Take my Technorati Cosmos Textpattern plugin for example. Sometimes Technorati returns duplicated results and I wanted to filter them: when looping over the list of links received from the Cosmos API call, I added them to an array and then looked there before printing the other links.

I looked PHP documentation and found the nice array_search() function. The documentation says:

mixed array_search (mixed needle, array haystack [, bool strict])

Searches haystack for needle and returns the key if it is found in the array, FALSE otherwise.

nice, the function returns FALSE if the item is not in the array, so I went and wrote my check:

if (!empty($cosmo->permalink) and array_search($cosmo->permalink, $items)) {
    // Skip the item if we have already seen it
    continue;
}

where’s the problem with that? Let’s see some examples.

$a = array(1, 2, 3, 4, 5);

var_dump(array_search(3, $a));
var_dump(array_search(1, $a));
var_dump(array_search(8, $a));

this prints, as expected:

int(2)
int(0)
bool(false)

but what happens if we put this in an if statement?

if (array_search(3, $a))
    echo "3 found\n";
else
    echo "3 not found\n";
if (array_search(1, $a))
    echo "1 found\n";
else
    echo "1 not found\n";
if (array_search(8, $a))
    echo "8 found\n";
else
    echo "8 not found\n";

the result is:

3 found
1 not found
8 not found

Why? Because 0 == FALSE and the second test doesn’t pass. Ok, let’s make it more specific.

if (array_search(1, $a) != FALSE)
    echo "1 found\n";

Wrong again, because 0 is still the same as FALSE. Don’t despair, a solution isn’t that far, any of these will work:

if (array_search(1, $a) !== FALSE)
    echo "1 found\n";
if (array_search(1, $a) >= 0)
    echo "1 found\n";
if (is_int(array_search(1, $a)))
    echo "1 found\n";

Functions that returns different data types are just evil, and they are everywhere in PHP. In this case, for example, they force you to use and grasp datatypes in a language which shouldn’t care much about them.

I just uploaded a new release of the Cosmos plugin to fix the duplicates detection.

PHP ain’t that funny, after all.

Technorati Cosmos in Textpattern

How do you get trackbacks without the spam and at the same time routing around your blogging software lack of that functionality?

Answer: you use some other tool, wich requires an even lower effort both on your and on other people’s side: Technorati Cosmos.

I started with a simple piece of code from Weblog Tools Collection, kept only the clever XML parsing trick and expanded it to a full Textpattern plugin. There was no license attached to that code, so I hope they are fine with me redistributing this.

So here is my Texpattern Technorati Cosmos plugin.

The plugin needs some easy configuration, in form of a Technorati Key and a cache directory wich must be writable by the web server.

To use it just place the tag <txp:mic_technorati_cosmos /> in your article form and you’re mostly done. With the default settings, the generated code will be like this:

<!-- Technorati Cosmos for http://currenturl -->
<h3 class="cosmos_label">Technorati Cosmos <a href=""><img src="bubble"></a></h3>
<ul class="cosmos_list">
    <li><a href="" title="">Cosmo title</a> &mdash; Cosmo excerpt</li>
    <li><a href="" title="">Cosmo title</a> &mdash; Cosmo excerpt</li>
</ul>

The label, the image and the excerpt can be customized and completely removed, please refer to the plugin’s help for more information. rel="nofollow" support is an attribute away, too.

You can see it at work in some of my articles and projects pages. Enjoy.

Update: New version with better duplicates detection