Deprecated Behaviour

The inane, sometimes insane, ramblings from the mind of Brenton Alker.

Following Hashtags on Twitter

The hashtags service allows you to see some interesting information, such as popular tags and a graph of a particular tags usage over time. It also offers the ability to follow a tag by providing an RSS feed, but I don’t believe it can provide a single feed of multiple tags. While I was at the PHP Quebec conference I was looking for an easy way to follow all the tweets with the various hashtags in use (there was some disagreement as to the “correct” tag).

I found that this can be done using twitter’s own search function, simply put all the tags into the “Any of these words” box on the twitter advanced search interface and run the search. On the results screen, subscribe to the URL for the “Feed for this query” (at the top right of the page) and put it into your favourite feed reader, set the refresh rate to every few minutes (you can probably set it lower if your software allows, but do your really need it?) and watch the conversation.

This allowed me to keep up with chatter at the conference, even from people I don’t usually follow.

PHP Quebec Wrap-up From a Conference Newb

As I am in Canada for only 3 more weeks, and we don’t get too many PHP conferences in Brisbane, I took the opportunity to attended my first ever PHP conference. I thought I would share my thoughts, and maybe those more experienced can help me do it “better” next time.

After flying across the country we checked into the hotel, the Hilton Bonaventure in Montreal. The front desk apparently didn’t know we were there for the conference because we didn’t “book with the others”. I’m not sure what that means, or what difference it would have made? The hotel offered free wireless in the foyer and conference halls, but not in the rooms. Luckily, we were close enough to the foyer to access their wireless from our room (once I sorted out some driver issues on my laptop).

Day 1

After missing most of the openning keynote on the first day in favour of eating (I didn’t know breakfast would be available) I jumped into the sessions. Starting with Matthew Weier O’Phinney’s Practical Zend Framework Jutsu with Dojo, which provided a practical overview to an area of the Zend Framework I have been planning on investigating, but haven’t yet got round to. This was followed up by John Coggeshall’s explaining their process of Building RIA Application in PHP. This wasn’t a talk I intended to attend (Sara Goleman’s talk was scheduled for this time, but was unable to attend due to illness) but it was interesting to see the differences in building a PHP application without a HTML front end.

After lunch, Derick Rethan’s looked into search and indexing. Of Haystacks and Needles, introduced MySQL full text, Selenium and Solr. While I have used Selenium, Solr seems like a useful step up for systems with higher requirements. The afternoon sessions were A tour of MySQL High Availability by Morgan Tocker, which talked about the difference between scaling for performance and scaling for HA, and techniques for the latter, for me there wasn’t much I hadn’t used before, but some of the monitoring tools warrant further research. Stupid Browser Tricks by Sean Coates, was in a similar boat. It was a good introduction to some useful browser side tools (Firebug, YSlow! and Selenium IDE) but I had hoped for a deeper look into Selenium. Isn’t everyone using firebug by now? FirePHP is a nice addition though.

Day 2

Day 2 started with a quick breakfast (I’m a fast learner ;)), then the PHP Code Review Part #1, with Sebastian Bergmann and Stefan Priebsch delving into some not particularly pretty examples of code from well known PHP applications such as Wordpress. It’s reassuring to know other people write and release bad code too :) I didn’t attend Part #2 of the session, where they took code samples from the audience and critiqued them. Instead I opted to drop in on Chris Hartjes expaining why Deployment Is Not A 4 Letter Word and that with some planning and appropriate tools, in your absence even the sysadmin should be able to deploy your application with confidence.

The pre-lunch keynote was John Coggeshall again discussing RIA in Beyond the Browser. Is the browser dead? Not yet, but it certainly has some growing competition. After a break, I listened to Ilia Alshanetsky talk about Premature Optimization Mistakes, focusing on optimising the server stack itself before delving into application level optimisation. Arguing it usually provides more results without the risk of breaking the application. PHP for the Enterprise then examined how PHP has reached a level where it is suitable for projects that were once considered the realm of “real” programming languages. Most of the talk discussed more technical details of scaling PHP to an enterprise level, such as database buffer sizes, performance monitoring and caching at various levels.

The day ended with the career fair which saw a number of, primarily local, employers (including the armed forces?) set up booths and discuss their work and employment with the potential candidates at the conference. While I wasn’t actively seeking employment, I did have a chat with some of the representatives. Given the location of the conference, it wasn’t too big a surprise that the majority were bilingual and in some cases French only offices.

Day 3

My final day of the conference started with Owen Byrne discussing Growing a Development Team While Building a Huge App at 500 miles/hour; which I attended, hoping to garner an insight into building a team and managing agile development on a large project. While the project was an interesting one, Owen seemed to be more interested in giving out t-shirts and I didn’t feel we got very deep into the whole process. Being a fairly heavy user and fan of Zend Framework, I joined Matthew Weier O’Phinney in his search for some of Zend Framework’s Little Known Gems. The talk was targeted at using the components in isolation and I discovered a number of components that may come in handy in future projects, with or without the MVC stack.

Morgan Tocker then talked further about MySQL, this time focusing on performance as opposed to high availability. There were a few points about the inner working of the InnoDB storage engine that got my attention, including some builds available from Percona we may need to look at.

The round-table Framework Comparison, featuring Fabien Potencier (Symfony) Derick Rethans (ezComponents) and Matthew Weier O’Phinney (Zend Framework) seemed to indicate that all 3 frameworks solve much the same problem, they even went as far as agreeing you should use components from the other frameworks when your primary framework doesn’t include one. Much different to the “my framework is better” “discussions” we too often see.

Finally, Chris Shiflett addressed Security-Centered Design: Don’t Just Plan for Security; Design For It provided an alternative look at some interesting security topics. Instead of focusing on technical details, he primarly focused on security from a user perspective as “user perception is as important as reality”. Giving examples of various recent attacks on high profile sites that, while not actually the fault of the site, would be perceived as such by most users. He also put forward ideas about using “ambient signifiers” to assist in the fight against phishing, and how the normal (request-reload) web model can mean important information is missed due to “change blindness” including a live demonstration. He suggesting AJAX might be a suitable solution in this case (as long as it’s still accessible of course).

Conclusions

All-in-all the conference was a great experience, the hotel was really nice (especially compared to some of the hostels where I usually slum on my travels) and the talks were wide ranging and generally well presented.

Some of the material I found too “introductory”, but I think that may be because I primarily attended sessions on topics I am familiar with hoping to learn more, whereas using the talks as introductions to new topics might have been a better idea. How do people usually select talks?

I also didn’t attend much in the way of “extra-conference” activities; social events outside of the conference schedule. I am a little disappointed about this, as it would have been good to chat to some members of the community in a less formal setting, so this is something I think I would do much more of next time. And there will be a next time.

Converting a Flat Array With Parent ID’s to a Nested Tree

Storing hierarchical data in a tabular data structure such as a database is not uncommon in many applications (eg. threaded comments on a blog entry, or a navigation menu structure). The “Adjacency List” method; probably the most common, involves storing a reference to the parent in each of the children.

Here is a snippet for converting the rows stored using the adjacency list method into a hierarchical array in PHP. My goal was to do this in 1 pass, without recursion. I ended up using 2 passes, I think 1 pass is achievable if you can guarantee the parent will always be returned before all of its children. But since I couldn’t, the first pass is to change the id of the row to be the key of the array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
function convertToTree(array $flat, $idField = 'id',
                        $parentIdField = 'parentId',
                        $childNodesField = 'childNodes') {
    $indexed = array();
    // first pass - get the array indexed by the primary id  
    foreach ($flat as $row) {
        $indexed[$row[$idField]] = $row;
        $indexed[$row[$idField]][$childNodesField] = array();
    }

    //second pass  
    $root = null;
    foreach ($indexed as $id => $row) {
        $indexed[$row[$parentIdField]][$childNodesField][$id] =& $indexed[$id];
        if (!$row[$parentIdField]) {
            $root = $id;
        }
    }

    return array($root => $indexed[$root]);
}

// Usage:
$rows = array(
    array(
        'id' => 1,
        'parentId' => null,
        'name' => 'Menu',
    ),
    array(
        'id' => 2,
        'parentId' => 1,
        'name' => 'Item 1-1',
    ),
    array(
        'id' => 3,
        'parentId' => 1,
        'name' => 'Item 2-1',
    ),
    array(
        'id' => 4,
        'parentId' => 1,
        'name' => 'Item 1-2',
    ),
);

convertToTree($rows);

// Produces:
array (
    1 => array(
        'id' => 1,
        'parentId' => NULL,
        'name' => 'Menu',
        'childNodes' => array(
            2 => array(
                'id' => 2,
                'parentId' => 1,
                'name' => 'Item 1-1',
                'childNodes' => array (
                    4 => array (
                        'id' => 4,
                        'parentId' => 2,
                        'name' => 'Item 1-2',
                        'childNodes' => array (
                        ),
                    ),
                ),
            ),
            3 =>  array (
                'id' => 3,
                'parentId' => 1,
                'name' => 'Item 2-1',
                'childNodes' => array (
                ),
            ),
        ),
    ),
)