Phase.org

Posts by tag: php

PHP: What's to learn?

2009-01-29 19:07:00
Those who know me or are familiar with this blog will know I often bemoan (aka: rant about) the lack of good PHP software engineers, or the mass of "junior" ones.

But it might be worth thinking about why this lack arises. I said, in my recent "Getting started in PHP" post:

If you're not interested in becoming great, please don't start.

While probably a touch harsh, I feel it's a valid sentiment. But how do you become great anyway? How long does it take?

To be honest, I don't know. I've only been doing this for 10 years professionally.

So, am I slow, or does it really take over a decade?

Well, at the risk of a "piece of string" answer, it depends on two things:

- How much you need to learn
- How fast you can learn it

My feeling at the moment is that there's a great deal to learn, and it's not often well, or coherently, taught. Even finding out what you need to learn can be really tricky.

However, I'm going to try and throw together a partial list, to try and get some idea of just what you have to know to be good in this game - and what that means in terms of how long it takes a developer to "mature".

As per the previous post, you'll need to start off with some basic coding principles and grammar; statements, variables, and functions. Then, wrapping those into classes.

You'll need a coherent idea of how to properly manage your code library and file inclusions (ideally with a class autoloader), which tends to lead to a coherent naming strategy.

Then, I'd strongly recommend learning TDD (recommendations on good sources for learning it gratefully received!). Not only does this help you write stable code, in a way that's useful in commercial environments, it also helps you learn the importance of good code encapsulation, and of dependency management. It's often considered a fairly advanced topic, but my feeling is that it should be learned as early as possible. TDDing your early code will also greatly increase its lifespan.

If you want your code to stick around and evolve, you *must* learn version control. Personally my recommendation is for Subversion, but there are many people who prefer Git. (You're advised to google these terms liberally). Your code's no use if it's scattered all over the place and not backed up, and a repository will help keep your code together and safe.

At some point very early on, and as mentioned previously, you need to learn about security. However, you can reduce your exposure to risk by using good practices, and data access layers such as prepared statements, PDO and Zend_DB. But be aware that there's a lot more to it than that!

Once you start looking at this sort of library or abstraction it's worth taking more time to look at frameworks and application structure. The MVC model is one key design you should learn, but it's only one of a wide range of Design Patterns which form an advanced vocabulary of development.

Design Patterns form the advanced building blocks of developments, but you should also advance your development practices - your tools, effectively. The techniques you should learn are collectively known as "Pragmatic Programming", and are neatly encapsulated in the book "The Pragmatic Programmer", which you might as well buy and read now, because you'll be a better developer afterwards.

These formalised approaches and skills mark a transition in your approach to creating code and applications, from "mere" development to software engineering. A hobbyist can certainly be a developer, but engineers are skilled professionals and experts. Much as it takes 3-4 years at a University (in the UK at least, more elsewhere) to become an engineer, it can take that long, plus a few years of practice, to truly grasp the skills of software engineering. And, as things stand, I'm personally dubious that university courses exist that give you a broad and modern enough skillset.

Even once you're engineering your software, rather than just building it, there's more to learn. Much as hardware engineers attend conferences and read technical papers, software engineers need to keep studying at a postgraduate level. These topics are widespread and continually being developed and discovered, but include continuous integration, load testing, scalability. You'll also need experience in the specific tools of your particular domain; this can include advanced SQL such as stored procedures & triggers, the full capabilities of your framework, use of advanced javascript toolkits, ajax, DOM & xpath and so on, before you even get to third-party APIs for other sites.

And there are also auxiliary skills that don't directly relate to development; configuration of servers, estimation skills, Scrum development practices, code reviewing; you'll need many of these to work in a team.

So, there's plenty to learn and, as said before, you won't stop learning. But, given some idea of your syllabus, a few pointers to resources, and plenty of interest and support, you can certainly build a very strong skillset in a few years. One of the problems I've felt over the years while learning is that it's very hard to know what I should be studying, which costs you time and direction. Hopefully the above list will be of some use; for more, just keep reading, attend conferences, and consult your local user group.

So who is Microsoft anyway?

2008-12-14 22:31:00
"Microsoft? What on earth do they want to have to do with PHP?", I was asked incredulously last night.
Well, apparently, quiet a lot, although calling it "The greatest love story as yet untold" may be going a bit far (and possibly even a little creepy?)

To many of us, Microsoft is still seen as the antithesis of the Open Source world, something due in large part to their own behaviour. Most developers who've been around long enough to recall the browser wars, the EU antitrust case, the battles Samba used to have to interoperate, frankly don't trust them. Indeed my own last significant interaction with them was when we were developing the Sender Policy Framework, and Microsoft wanted to leverage their own Intellectual Property into it and then require a "RAND-Z" licence on top of it - which would have crippled open-source adoption, and thereby the standard itself.

So yeah, I'm not really predisposed to liking Microsoft.

But that experience was several years ago, and the Microsoft Behemoth is starting to turn. Led internally by figures such as Hank Jannsen and (in the UK) Will Coleman (who apparently exists only on Twitter), there's a strong "If you can't beat 'em, join 'em" pro-open-source movement gathering steam.

Microsoft appear to have realised that when they try and beat open source technologies such as PHP, everyone loses. That gives them the choice of ignoring it and hoping it'll go away, or working with the PHP movement to try and make IIS a good choice of platform to run PHP on (previously it's been dog-slow and unstable) and MS-SQL a good database to pair with.

Fortunately, they've gone with this last option, and there's a significant and growing effort within MS to make this work well, as can be seen at their Open Source blog.

It was for this reason that I (and a number of other UK "PHP community leaders") was invited to a "Microsoft PHP Community Event" last week. They're trying to engage the community at its own level, which in this case meant a few talks, and quite a bit of Q&A, in the back room of a pub. This comprised a video presentation from Hank Jannsen, and talks from Will Coleman from the MS side together with Ivo Jansch and Scott MacVicar from the community side. As this was all done in a Pecha-Kucha (20/20) fashion it was all slightly hectic. The community asked for a lot, and Microsoft promised a lot, in terms of technical assistance, time, cash, and attitude change.

It's worth admitting that MS already do a far bit - technical assistance to the Samba project, financial aid to the Apache foundation, and technical improvements to Zend Core which have brought the speed of PHP on Windows/IIS servers to parity with that on Linux/Apache. The question is whether they can do enough both to convince the community, and to convince businesses to combine Open Source and commercial platforms.

It'll be worth watching, but they've got some work to do.


Special mention has to be given both to the food at the Windmill pub - Sausage and Mash as finger food? How about Fish, chips and mushy peas? - and to the goodie bags; Santa hats, Xbox 360 games, whisky, very small trees, and and crunchie bars ("To make the credit crunch fun!"). Well, Will's a nice guy, but sometimes he worries me.

Getting Started in PHP

2008-12-06 16:06:00
So... you'd like to get in on the act and start coding PHP? Perhaps you'd like to add a few features to your homepage, or perhaps you're looking for a career shift? How do you get started in the Brave New World of PHP?

The main thing you'll need is a strong desire to learn and to improve. There are thousands of junior developers out there who frankly have poor skills and produce terrible code, and who are unlikely ever to get much better. By just displaying a reasonable amount of determination and drive, you can rise above them and become skilled and highly employable! If, on the other hand, you're not interested in becoming great, please don't start - the shallow end of the pool is full enough already.

There are three key points you'll need to bear in mind:

1) You're aiming at a moving target. The discipline of software engineering, and the PHP language, are both young and evolving.

2) Security is absolutely key to your code! Unlike 20 years (or so) ago, when I started coding in BBC Basic and the code never left the room, your site and the code on it will be out in the wild from day one, and will need to be resistant to numerous security attacks. The good news is that security basics aren't that difficult to learn.

3) You will never stop learning. And it'll (usually) be fun.

There are also three areas you'll need to study in:

Firstly, the grammar and rules of the language you want to learn, for which you can start with a basic book on PHP such as Learning PHP 5 or the slightly more advanced Programming PHP.

Secondly, the tools and techniques of software engineering. Much as you wouldn't build a house without some architectural understanding, or a car without some key ideas in mechanical engineering, your code will be immeasurably improved if you understand the best techniques to use. To a large extent, these techniques are language-independent, and will serve you well whether you end up coding in PHP, C, Java or ay other modern language. My own personal favourite book on this topic has to be The Pragmatic Programmer.

And thirdly, you'll need an understanding of the environment you're working in, both with regards to security (for which I invariably recommend Chris Shiflett's Essential PHP Security) and wider issues such as the platform you'll be running on, and the wider functionality and expectations of the web.

The good news is that it's not all book learning, and you won't be on your own. However, I've presented these books first because the community is also far keener to help someone who'll help themselves and, if you choose to splash out on professional training, it never hurts to get a head start to make the best of your investment.

So, who is out there to help you? Well, tens, possibly hundreds, of thousands of people, arranged into various types of online and real-world communities. If you're in London UK, where I am, you should join PHP London; sign up to the mailing lists and join us at the social meets. If you're elsewhere, take a look at PHP User Groups or MeetUp.com to find a local group.

Does that feel a bit too much like jumping in at the deep end? Don't worry about that. These communities are here to support you at all levels, and as per this recent piece by Chris Cornutt, you're unlikely to become a great developer on your own. We could save you a few years of confusion, and do wonders for your skills and earning power!

If you do want to go for professional coaching, the best place to go in the UK is probably iBuildings, who are Zend's partners for the UK and Netherlands. They can provide a range of training for various skill levels - I and my team took some a few months back and found it very useful. However I should probably disclaim here that I've since become friends to a few of the iBuildings staff, and I will (much as Paul will hate me for admitting this) point out that you can become a good developer without their help! For individuals in particular, the training can be quite an investment, and so self-study can be a good option.

So, where (and how) to self-study? Well, as you're reading this I presume you're already familiar with various blogs and online sources, but I'll point out that PHP London has a collected RSS feed (including this blog) at http://feeds.feedburner.com/PHPLondon, and you'll find many more blogs at Planet PHP. Another good resource is the hardcopy (and recently relaunched) PHP|Architect magazine, which is a must at its new price.

Personally, I find self-study most productive when I have a goal. One I'd particularly recommend would be the Zend PHP5 Certification. This is not a basic certification (for that, look at something like BrainBench), and may take you a year or two to learn enough to pass if you're new to programming, but that's precisely what makes it useful. If you can pass this, you probably know what you're doing. Note that while there is a study guide for the certification, it's not enough to refer to this book alone as it's mainly a syllabus - you'll need to study from other resources to pass.

Well, I figure that that should get you started! As ever, do feel free to comment or drop me a line with any ideas or queries.

Going beyond actions in Zend Framework MVC

2008-11-21 20:45:00
The basic model of Zend MVC is the use of Modules, Controllers and Actions. Each URI is translated via a set of specified or default routes to call a specific action, which, in the default behaviour selects and populates a view which is then automatically rendered.

This works well for any behaviour which is URI-specific, but doesn't work so well for controller-wide or site-wide behaviour, or behaviour repeated in multiple (but not all) actions.

These are handled in plugins and helpers, but precisely how to use those can be confusing (by which I mean, it took me a while to work out). There are multiple event-triggered functions that can be implemented to run at various times, as well as those which are called according to route, or manually.

The complexity further increases because Plugins, Action helpers and even Controllers can fire on events. Plugins have six possible event triggers, and controllers and helpers can fire on preDispatch and postDispatch.

There's a useful visual guide to those timings at http://surlandia.com/2008/11/03/zend-framework-plugins-action-helpers-and-controllers-life-cycle-during-dispatch/

As for particular use cases:

Plugins are registered with the front controller in the bootstrap file, and fire at any of the 6 triggers for all routes / actions.

Controller events (pre/postDispatch) fire at specific times when their own controller is routed, alongside the appropriate Action functions which tend to perform the bulk of the work.

Action helpers designed as pluggable functionality that can be registered and called as required (usually by Action functions), but can also "prepare" and "clean up" after themselves by means of their triggered functions.

The role of this post is only to clarify (partly for my own benefit) the above options and differences; for more detail, Matthew Weier O'Phinney has some excellent articles at Zend DevZone:
http://devzone.zend.com/article/3372-Front-Controller-Plugins-in-Zend-Framework for Plugins and
http://devzone.zend.com/article/3350-Action-Helpers-in-Zend-Framework for Action Helpers.

Using Zend_OpenId_Provider

2008-11-21 12:17:00
Zend Framework's Zend_OpenId_Consumer makes accepting OpenID logins on your site pretty easy, but its companion, Zend_OpenId_Provider is a little harder to get on with.

There's a few reasons for this:

1 - As per the philosophy of Zend Framework, you're given key parts of the tool, but have to fill in a lot yourself.

2 - There's a lot more data to manage and store for a Provider than a Consumer, and the OpenID system deliberately puts the complexity on the Provider side.

3 - The documentation of Zend_OpenId_Provider is, frankly, not too hot. To quote:
"Building OpenID servers is less usual tasks then building OpenID-enabled sites, so this manual don't try to cover all Zend_OpenId_Provider features as it was done for Zend_OpenId_Consumer."

The documentation is, unfortunately, written in somewhat stilted english, and the examples given are over-simplified and not altogether clear.

Now, there's no point simply ranting about this, as someone will quite reasonably request more detail...

So, given that ZF is a community effort, and that I've managed to work out enough of the code to get a basic provider running, here's a quick guide on how it seems to work:

As per the flowchart at http://framework.zend.com/manual/en/zend.openid.html#zend.openid.introduction.how, it's a multi-step process:

First, the user requests a login to the consumer site by provide an OpenID URI.
The consuming server checks the page at that URI for a server delegation metatag, and then contacts the server this identifies (optionally following a further delegation chain).

The providing server must accept a direct HTTP request from the consuming server and call:
$server = new Zend_OpenId_Provider; // Instantiate server with default settings
echo $server->handle(); // By default, look in $_GET for openID data and respond to it.

This can be done as for any other page so long as you only ouput the return value.

Unfortunately, this default behaviour will simply return an OpenID CANCEL command to the consumer, because:
- The Provider will call self::hasUser($id), which in turn calls Zend_OpenId_Provider_Storage->hasUser($id)
- The default storage mechanism has no users until configured (hence the hack in the first example in the docs)
- Failing to locate the user causes Zend_OpenId_Provider to decline the request.

So, we need to provide a form of storage that will respond 'true' for an ID we should be able to serve.

The very simplest way to do this is to subclass Zend_OpenId_Provider_Storage_File and pass that in to the provider class's constructor (it accepts any object inheriting from Zend_OpenId_Provider_Storage as a 4th parameter, but uses the file variant if none is provided).

The only function you'll need to override at this time is Zend_OpenId_Provider_Storage::hasUser($id). My personal quick hack was:

public function hasUser($id){
return ($id==='http://myuser.openid.server.com/');
}


Obviously for production you'll want to do something a bit smarter, but for now it's enough to give you the idea.
You could also try to use somthing like the documentation hack to register an id in the file storage, but I'd rather make ZF work my way.

So, if the ID is known (even if it has no relation to the current provider site visitor), the Provider will associatte with the Consumer in order to be able to confirm the identity securely. This association is stored by Zend_OpenId_Provider_Storage::addAssociation(), but for now I'm letting the Zend_OpenId_Provider_Storage_File handle this.

Once it's associated, the Provider will (I believe) see if it's aware of the owner of that identity being logged into itself (via a prior call to Zend_OpenId_Provider::login()). If so, it will move on to confirming that the user trusts the consuming site (ie, is happy to confirm their identity to it).
If the user is not logged in to the provider (NOT the same as being logged into the providing SITE), the user's browser will be directed to the provider's login page, as specified as the first parameter in the provider's constructor. Note that if the login URI is not provided to the constructor, a default URI is used as per the documentation.

This login page should verify the user's identity by whatever means the providing site already uses, then call a redirect to the trust page (the second constructor parameter). Note however that Zend_OpenId_Provider is written to expect that you log into itself directly (by username and password) and is written in a way that makes it hard to write the Zend_OpenId_Provider_Storage::checkUser function that needs to validate the username and password. Unusually for Zend Framework code, the encapsulation here is too weak, and developers will often need to replace or sidestep this particular bit of functionality.

Once the trust page is reached, the provider needs to verify that the user is happy for the consumer to know their identity. There are various options here; if you use the full built-in abilities of the provider, you may have previously told it "This site is always OK" or "This site is never OK". It should use that data (as stored by the Storage, IIRC) at this point if available, otherwise it will display the Trust page.

Note - there's a *lot* going on under the hood of the provider, and without testing every route I'm not exactly sure of program flow! For this guide, I'm covering the basic operation, and the principles, but for trust storage you'll have to experiment for now. It seems likely that if the user is already logged in to the Provider, and has designated the consuming site as "Trust Always", then Zend_OpenId_Provider will not try to display either the login or trust pages.

Finally, whatever method you use to verify trust, if you the user agrees to it, you then need to call
$server->respondToConsumer($_GET);
which will be the Provider's last act, confirming your identity and returning you to the consuming site.


To summarise the code required (we'll assume an MVC environment; this code isn't tested as-is):



class OpenIdServerController extends Zend_Controller_Action {
function init()
{
$this->_provider = new Zend_OpenId_Provider(
'/openid/server/login', // login path
'/openid/server/trust', // trust path
null, // default user session manager
new My_OpenId_Provider_Storage() // our tweaked storage class
);
}

function serverAction() //This is called first, by the consuming server
{
echo $this->_provider->handle(); // handle 'GET' params by default
exit; // Don't render views, etc
}

function loginAction() // The user is directed to this page if they're not logged in to Zend_OpenId_Provider
{
if(/* we can verify this user */) {
//optionally call $this->_provider->login() to maintain user identity on providing server
Zend_OpenId::redirect("/openid/server/trust", $_GET);
} else {
// Display login form and post back to this page
}
}

function trustAction() // The user is sent to this page after being logged in
{
if(/* we have permission to trust this consumer */) {
$this->_provider->respondToConsumer($_GET);
} else {
// Display a form asking whether to trust this consumer; post back to this page
}
}
}

Refer to the ZF manual for suggested forms.

Our hacked My_OpenId_Provider_Storage just looks like:
class My_OpenId_Provider_Storage extends Zend_OpenId_Provider_Storage_File
{
public function hasUser($id){
return ($id==='http://myuser.openid.server.com/');
}
}



NOTE that this process basically expects the user to log in, or be logged in, and to re-verify trust each time. Using the "Provider Sessions" is beyond the scope of this guide.

PHP UK Conference 2009 Call For Papers

2008-10-30 08:20:00
PHP London are pleased to announce their 4th annual UK PHP conference, building on the success of previous events and accommodating the continual growth of the PHP community and PHP development industry.

The event will take place on Friday February 27th 2009 at Olympia Conference Centre, London. Registration will commence in December 2008 and those interested in attending can create an account on the PHP UK Conference website at http://www.phpconference.co.uk/user/register and sign-up for notifications of updates to the website. Important announcements will also be made to the PHP London announcement mailing list:
http://lists.phplondon.org/cgi-bin/mailman/listinfo/phplondon-announce

The Call For Papers is now open and finishes at the end of November 2008. Speakers interested in talking at the event can submit their details at http://www.phpconference.co.uk/call-for-papers whilst potential sponsors can contact the conference committee using the form at
http://www.phpconference.co.uk/contact

All known information about the conference so far is available at http://www.phpconference.co.uk. We hope to see you at the event next year!

(I'm the treasurer of PHP London and on the organising committee of the conference)

What's in a name\space?

2008-10-28 10:37:00
OK, so the decision has finally been made (again) on the PHP namespace separator, and they've chosen the backslash, '\'.

Leaving aside the sheer number of people who think '/' is a backslash, this is obviously a dumb idea. One of the dumbest things Microsoft did (and there's not generally considered to be a shortage) was to use backslash as the directory separator. It's an escape sequence! It always made coding file paths a complete headache.

Unfortunately (perhaps), like democracy, this is worst possible choice except for all the other options.

'::' is ambiguous with class scope. ':::' is a headache to read or differentiate for anyone with any sort of visual issue / dyslexia. Pretty much every other piece of punctuation on the average keyboard is already taken; multiples of symbols are a mess. Combinations like :) are hard (at best) to take seriously.

The only character I can find on the (UK Mac) keyboard that isn't yet used is ยง. And frankly, I really can't see that catching on; I don't even know what it's called.

Tags: php

So you want... some content?

2008-10-02 22:54:00
Occasionally I get reminded that there are actually people reading this thing, and that it's more useful to them when I actually write something on it. Fair enough - I'm aware that, due to a combination of illness, holiday and work - and the fact that I've been actually writing code, rather than writing about it - the series has stalled a bit.

It's not going to restart this minute, as it's 11pm and I'm just back from PHP London, but I'll continue where I left off shortly. And, having done some work with it recently, I'll add PhpUnderControl / CruiseControl to the topic list - I've found it to be much more useful than other Continuous Integration tools I've tried.

I'll also, at some point, talk more about the human side of running a team (it's been very technical so far), but in the meantime, I promised I'd pass on some resources.

Firstly, my Agile PHP Development Bookshelf list at Amazon, which contains some recommendations on technical and management books.

Secondly, a couple of podcasts that have been recommended to me (but are, I have to admit, still waiting to be listened to): Manager Tools and Stack Overflow.

I should probably dig out my blogroll too, but that's on another machine...

(and yes, I *will* add tags to this site at some point so you can filter content....)

A small project: new Eve Online tools

2008-08-28 19:16:00
For some time now I've been playing the MMOG "Eve Online"; a game of epic space battles and warring factions in the far future (and so on). Think "Massively Multiplayer Elite with Babylon 5-style graphics".

Eve is famous for various key ways it differs from most other MMOGs:

1) It's unsharded. All players (0.25 million at the last count) play within one server cluster, and any player can (subject to not getting blow up in transit) travel to, and play with or against, any other player.

2) It's extremely free-form. you can choose to mine, build, invent, explore, run missions, fight solo, run megacorps, carry freight - there's a vast in-game economy - and change roles as rapidly as you can train new skills.

3) The learning curve is incredible (although there are no shortage of newbie-safe areas); it can literally take years (of real time, not in-game time) to qualify to fly the largest ships, and months for some of fairly common intermediate ones. The skill tree is colossal.

In other words, it's a highly complex game that occasionally causes you to reach for a spreadsheet (or dedicated app) to work out what to buy, how to equip a ship, or what to study. Fortunately, there are very good tools - and, even better (for my purposes), there's a good supply of data through an API and periodic DB exports.

The DB and API (and a certain degree of transparency in sharing key formulae) allow the use of skill planning apps such as EveMon and ship fitting tools such as the Eve Fitting Tool. They also allow very simple tools as Skill Monitors, and more complex tools that let you search and analyse all your in-game assets.

At the moment, there are some very good tools for Windows, a few less-great ones for the Mac, a decent range on the web, and no iPhone apps. So, I'm looking to fill that gap.

I'm not a Mac coder; I've never written a line of Objective C or cocoa; I'm a PHP developer. But that also means I've a decent object-oriented programmer, and I've got a reasonable C/C++ background. So, I'm initially experimenting with the (XML/REST) API in PHP, while I learn enough about it and Objective C to move to the desktop or the phone.

So far, I've got a crude skills monitor (was there a shortage?), and, more interestingly, a complete asset viewer that also lets you see complete fittings and cargo of all your ships. These tools are currently web-only (hosted at phase.org) and currently open to a very small closed alpha test. However, they will grow, so if you're interested in access or have suggestions, comment here. Priority for alpha/beta access will go to members of my Corporation (Ominous) and Alliance (Ethereal Dawn).

(For what it's worth, the other thing I'm looking to write for the iPhone will be a decent LiveJournal client).

Installing PHP 5.3 on Mac OSX 10.4

2007-10-16 15:29:00
NOTE: This will not work on Leopard / 10.5 - the httpd on there runs as an x86_64 binary, and the instructions below create an i386 php5 build, which can't run as a shared module. Fink libraries do not yet appear to play nice with x86_64 builds of php5.

My current workaround is to rebuild apache from source as i386, with ./configure --enable-rewrite --enable-so - note that this means there will be 2 apache binaries in the system unless you configure to install over the one apple provides.


PHP 5.3 appeared on snaps.php.net today, and one of the features therein is namespacing. Now I've been curious about namespacing for some time - my code's currently full of class prefix_classname{} declarations - so I thought I'd like to try it out.

Now, the first slightly trick issue here is that I use a MacBook Pro as my main dev system, and installing PHP on these systems from source is supposed to be a bit tricky - so I've been using Marc Liyanage's prebuilt packages for some time.

However, while installing from source is certainly non-trivial, it's not actually all that tricky.

I started off with Guillome Boudreau's installation guide, in combination with my own old install instructions and config statement. And a PHP 5.2 stable tarball, as I thought I'd try running a known-working codebase before diving into development code.

Note that I'm going to assume you have some basic experience unpacking tarballs and installing PHP on linux here, and am going to miss out some steps. If you don't, read my older post first.

First things to note - the package list I show in that old post simply doesn't work with fink's apt-get command line - most packages which would be something-dev on debian seem (corrections welcome) to be something-shlibs in fink. So, I started off with a reduced fink line of: sudo fink install libjpeg libtiff libpng3 libmcrypt ming flex, which all seemed happy, then tried the configure command I last used on my live server (ubuntu linux):

./configure --disable-cgi --disable-rpath --disable-debug --disable-magic-quotes --disable-posix --with-apxs2=/usr/bin/apxs2 --with-mysql=/usr --with-zlib --with-dbx --with-ctype --with-openssl --with-pcre-regex --with-gettext --with-mcrypt --with-mhash --with-iconv --with-gd --with-jpeg-dir --with-png-dir --with-zlib-dir --with-xpm-dir --with-ttf --with-xsl --with-tsrm-pthreads --with-tidy --with-freetype-dir --enable-gd-native-ttf --enable-calendar --enable-mbstring --enable-spl --enable-ftp --enable-bcmath --enable-sockets --enable-dom --enable-xml --enable-soap --enable-libxml --enable-session --enable-simplexml --enable-memory-limit --with-curl=/usr/ --with-curlwrappers --with-pspell --enable-pdo=shared --with-pdo-mysql=shared --with-pdo-sqlite=shared --with-sqlite=shared --enable-exif

Now, that didn't entirely work - not surprising as there's a few server-specific paths in there. Also, some of the packages needed weren't installed yet. Saving you the gory details of all the iterations I went through, I also executed sudo apt-get install freetype freetype-shlibs to try and solve a 'missing freetype.h' error (it didn't work, I've sacrificed freetype support for now), sudo apt-get install libmhash libmhash-shlibs to add the missing 'mhash', and sudo apt-get install mysql14-dev mysql14-shlibs for missing mysql client libs. I'd rather have installed mysql15-dev as those are mysql version 5.x, but the packages are missing in fink. It seems to work anyway.

I also admitted defeat on a few non-essential config options: --with-gettext (due to a complaint about a missing intl.h) and --with-pspell as I couldn't be bothered to install it (most browsers have spellchecking now anyway). Finally, the config script ran, but warned me:

Notice: Following unknown configure options were used:

--with-dbx
--with-ctype
--with-libjpeg=/sw
--with-libtiff=/sw
--with-libpng=/sw
--enable-memory-limit


so you could probably drop those too.

Then on compiling it, I got complaints about a syntax error in tidy.h, so I dropped the tidy extension too.

So, the config options I used in the end were:

./configure --disable-cgi --disable-rpath --disable-debug --disable-magic-quotes --disable-posix --with-apxs --with-mysql=/sw --with-zlib --with-dbx --with-ctype --with-openssl --with-pcre-regex --with-mcrypt=/sw --with-mhash=/sw --with-iconv --with-gd --enable-gd-native-ttf --with-libjpeg=/sw --with-libtiff=/sw --with-libpng=/sw --with-jpeg-dir=/sw --with-png-dir=/sw --with-zlib-dir --with-xpm-dir --with-ttf --with-xsl --with-tsrm-pthreads --enable-gd-native-ttf --enable-calendar --enable-mbstring --enable-spl --enable-ftp --enable-bcmath --enable-sockets --enable-dom --enable-xml --enable-soap --enable-libxml --enable-session --enable-simplexml --enable-memory-limit --with-curl=/usr/ --with-curlwrappers --with-pdo-mysql=/sw --with-pdo-sqlite --with-sqlite=shared --enable-exif

This works, and compiles; running make test does throw up a few fails, but the result seems to install OK, and running phpinfo(), my unit test suite, and the code itself, seems to work quite happily.

As mentioned, the first run through of this was with 5.2; repeating the exercise with php5.3-200710161230 Just Worked.

At some point soon I'll start playing with the namespaces; however in the meantime I hope the above instructions help someone.

Tags: php osx

State of play

2007-10-15 23:07:00
So, I've fixed the RSS feed on phase.org, taking the chance to play with some PHP DOM code. The feed's actually built up as DOM operations - probably overkill for RSS, but an interesting exercise, and it should mean I can't somehow create a badly-formed feed. Although, as the post itself is encoded as CDATA, I'm not quite sure what'd happen if I tried to include the CDATA escape sequence. No, I'm not gonna try it now, it's late.

Why fix the feed now? Because Nigel James has come up with the great idea of aggregating the blog feeds from PHP-London members, and he was going to include mine 'til I broke the feed. Plus, my imagination has just been fired up by recently attending FOWA, *and* I've just got a new job, *and* I've got two weeks off, *and* I've been promising for far too long that I'd actually start blogging again. I've also been meaning to put some social and political content on here too (much as many other tech bloggers do) and Ming Campbell's resignation tonight provides as good a start point as any. Oh, and the revelation that people think I might actually be saying stuff worth following is useful too...

Testing potential developers and spotting bad PHP

2006-04-15 11:03:00

I recently spent a considerable amount of time interviewing candidates for a Senior Developer role. One of the main things I wanted to be sure of before they even passed the first interview was that they knew how to write clean, secure code.

Rather than take a large slice of time out in the first interview to *create* such code, I decided to write a piece of well-meaning but lethally dangerous PHP code such as a beginner might create, and ask for their comments on it. Now that I've finished interviewing (for this batch of developers at least) I thought I'd release that code with annotations.

It should be a useful example to anyone who wants to make their PHP secure, as it displays most of the common PHP security mistakes in about 40 lines, as well as a few more general beginner's errors.

I found out a number of very interesting things while interviewing:

  • Giving interviews is (by the 10th or so) harder work than taking them.
  • A lot of candidates assume that a "Senior PHP Developer" is a project manager who doesn't need to be able to understand or audit the code produced by his* minions.
  • Far too many "Senior Developers" with significant commercial experience don't know about security issues. This probably explains why so many websites get hacked.
  • The greater a candidate's involvement in the online community, the more they tended to know and care about security. One of the key things I was looking for was developers for whom PHP was more than a 9-5 job, and this experience very much justified that requirement.

As it happens I found out more about each candidate's security knowledge in the 10-15 minutes this test took than from 2-3 hours of pair coding in the second round interviews. From that, however, I learned a lot more about their own coding styles and personalities.

The moral of the story? Never hire a coder from his CV; make sure he's taken a real-world technical test first, with someone who can really evaluate the results at a higher technical level. Personally I'm unconvinced by memory-test, learn-by-rote certifications that are evaluated by computers; I'd rather draw my own conclusions about a developer.


* There were no female candidates. Coding, it seems, is still very male-dominated.

Tags: hiring php

How to be a good developer

2006-02-17 13:52:00
I don't usually cross-post blog articles from other journals to this one, but this one struck me as extremely useful; much like Chris' book I mentioned previously, this is something every PHP developer should read.

http://www.killersoft.com/randomstrings/2006/02/16/walk-the-walk-before-talking-the-talk/

PHP Conference UK, 2006

2006-02-11 11:00:00

Yesterday I attended the UK's first PHP conference at LSBU. This was a low-cost, volunteer-run affair organised by the local PHP user group - and it was admittedly a little rough around the edges. However it was competently run and, taking it as an enthusiast's conference rather than a professional one, very much satisfactory. The conference was sponsored by O'Reilly, City Safe, Packt Publishing, Word Tracker and Propel Recruitment.

The conference took the form of a day of talks held in a university lecture theatre, with coffee and lunch breaks, but no lunch provided (something which the organisers may not have planned on, although there were adequate food sources nearby). Further, there were a number of technical hitches during the day when the venue's equipment either failed or wouldn't integrate with the speakers' equipment (which admittedly threw a couple of faults of its own). Fortunately, these were not overly disruptive (with enough geeks, all bugs are shallow) and the venue was modern and comfortable with excellent accoustics and high-speed WiFi.

Being an enthusiast's conference, with WiFi, the audience was well-equipped with laptops and were thus able to take notes and explore websites linked from the talks; I'm sure many notes were taken and blogs posted. As is common at PHP-London meetings, most of the laptops were Apple Macs; the combination of functional desktop and unix architechture seems to be a popular one among PHP developers.

The first talk was given by Derick Rethans on "ez Components" - a PHP toolkit providing useful base functionality such as configuration reading and management, caching, cli and mail tools (among others). To me, this talk was useful on the basis of the development and coding techniques used, as well as in bringing me up to speed on a few PHP5 developments I'd not caught up with. The use of function namespacing (as in this site's codebase, but sadly missing from PHP itself) was of interest as I was wondering if this was just some weird idea that only I used.

Besides technical discussion of such things as SQL connection pooling, the actual subject matter - the component library - was interesting (and something I could conceivably use in future). The tools themselves (although not fully described) seem distinctly useful, and the knowledge of the coding techniques used gave me confidence in the quality of the library.

Unfortunately the talk over-ran (I presume Derick is not a particularly praticed presenter) and we didn't get the full material before the break, but I certainly learned something from the talk and would suggest that anyone needing a component library take a good look at this one, which seems to fit the open source requirements of high code quality and active development.

After a belated break (it having been pointed out to the organisers that the sponsors would not appreciate being deprived of face-time with the participants) we moved onto the second talk, and the most visibly nervous presenter, Pavel Kozlowski with a talk on "Pico and Dependency Injection". Now, before this talk I'd heard a fair bit about "dependency injection" from Marcus (from whom I suspect I've learned a great deal) but never really understood what it was; the word "injection" for me having very negative connotations of SQL and code injection attacks.

In fact that's not the issued. Dependency Injection is, if I may make a stab at a definition, the problem of providing code elements with their functional dependencies closely enough to be effective, but loosely enough to make unit testing and isolated development pratcical. Methods of providing such dependencies vary from calling 'new' within the dependent object, through use of a DAO registry to a fully-fledged DI container such as Pico.

I won't go into much technical detail, as these concepts are still fairly new to me, beyond saying that Pico essentially acts as a dependency "broker" which accepts registrations by classes (in part) according to the interfaces they provide or the requirements of their constructors. I'll leave the rest to the Pico site itself.

Unfortunately this talk also ran out of time, although it was probably fortunate that the organisers were keeping on top of time by now; I'd have liked to here more but at least have a useful start point.

Lunch was a "seek and ye shall find" affair; I found a Nando's (portugese spiced chicken chain) and had a very pleasant meal in the company of a Swiss delegate, but found that Nando's idea of "medium" is rather hotter than my own. The lunchbreak also gave me a chance to get to the O'Reilly stand and feed my tech-book habit; I walked out with the SQL cookbook, PHP Hacks, a Podcasting pocket guide and (given to me for free later) an book on PHPUnit. Something of a haul, but 30% off for show prices helped. I also notice O'Reilly are releasing a "Head-First" series with a much lighter "voice"; personally I didn't think the cartoony elements were for me but I'm told they've been well received. Certainly the presentation of "Design Patterns" as "Why make your own mistakes when you can learn from others" is an interesting approach...

After lunch, Matt Zandstra - Author, Yahoo! senior developer and, to be frank, rather disappointing speaker. Matt's material on "The Template Path" was at best tangentially related to PHP and the presentation showed every sign of being an in-house training presentation. It didn't map well to the audience, who weren't generally interested in code specifics of in-house material they were unlikely ever to use. Yahoo! were actually recruiting at the event and I have to say I think Matt sold them short. I've got a copy of his book at the moment and will withold judgement until I've at least taken a look at it, but I really couldn't find much beyond a simple but interesing design pattern to take away from the presentation.

Update: Evidently Matt can write pretty well; the Zend.com PHP5 exceptions article is extremely clear and readable. I suspect that if he'd billed his talk as "stuff you can do at Yahoo! if we hire you" and it had been one of alternative tracks, the talk would have worked much better.

Following that, however, a much more interesting presentation by Christopher Kunz: "I've been told to scare you awake". Well it wasn't quite that terrifying (as I'd already been studying PHP security recently) but it did make the point that "there's always going to be one more vulnerability". Some wince-inducing examples of "wild code" were shown but I was already familiar with the issues presented (not that I'm entirely immune to them in my own code yet). There were also some valid points on vulnerability disclosure and responsibility.

The focus of the talk, however, was the PHP Hardening patch, designed for and by ISP administrators to protect themselves and their users from internal and external attacks. It's not a complete solution to security - it doesn't claim to be - but it's a good start, and seems to be compatible with most well-written code (at least my own apps still work when I recompiled PHP after adding it on this server). I'll let the patch speak for itself, but I strongly advise that you take a look at it, and also at Christopher's book (at least, once it gets an english translation - any volunteers?), at which I was able to get a quick look after the conference.

The final talk of the day was something of an oddball - Harry Fuecks of SitePoint basically talking about why AJAX was overhyped and tricky to use effectively (and often misused) (talk resources here). Harry, this isn't news! Any technology can suffer from these issues and it's down to the developer to work around them. Had this been a presentation on how to work around them it might have been more interesting, but in the end I wasn't told anything I didn't know (in fact I'd already solved some of the issues mentioned in my own implementations) and the negative topic was unsatisfying. It might have served better on a multi-track conference where there were alternative topics.

That said, Harry's actually a pretty good speaker, and with a better topic (and he's certainly got the material) I could have really enjoyed his presentation; certainly his site's extremely useful (if slightly over-commercial, to my mind).

After Harry's talk there was the gathering of the feedback forms and then the Closing (which I imagine the organisers didn't gather much feedback on...) which involved a number of book giveaways and the traditional "Thanks to all". Following this, a number of us repaired to Living Space for free beer (courtesy of CitySafe, who are hiring) and general chat and (nominally) blogging; it was at this point that I installed the Hardening patch on this server (and *then* discovered an XSS attack on one of the sites had recently succeeded - I think I know why, though).

All in all, a good event; certainly worth the time and money, and a very promising first event. Congratulations and thanks to the organisers, and thanks also to all sponsors and speakers.

Update: It occurs to me that, while not all the talks were "great", no-one can really expect every single topic at a conference to excite them and that this is really just an artefact of a single-track conference. It'd be interesting to see if next year's can be made multi-track.

Disclaimer: I am a member of PHP-London but was not involved in the organisation of the conference. Hopefully I will be able to help out next year if the group decide to repeat the exercise.

Review: Essential PHP security

2006-01-23 20:07:00

If you write PHP code, and want to make any pretence at security, read this book. Clear enough? This book's not cheap at something over £20 for 100 pages, but it's clear and readable. You won't find every potential security flaw in your PHP code in here, but the vast majority are covered and the techniques advised will cover most eventualities. Plus you can follow Chris Shiftett's blog at http://shiflett.org/ to keep up to date.

PHP is often criticised as an insecure language - in fact it's an easy and powerful language that gives you enough rope to hang yourself. In particular, because it's easy to pick up (and I'd recommend it as a first language) it's used by new programmers who aren't security aware. This book isn't ideal for the PHP newcomer - you'll need some understanding of the language, but with that you'll find the content of the book clearly laid out and easy to follow. Even if you're already aware of many security issues, this book will add a couple more and act as an invaluable checklist.

Update It's been pointed out to me, quite accurately, that this book is not a complete guide to securing PHP applications; however I feel that its small size means that developers have no excuse for not reading this, or a more complete, book; reading this should at least make you understand what it is that you need to learn about.

More on directory-style paths

2005-12-04 14:16:00
The following was emailed as a response to a user query about the techniques mentioned at
http://phase.org/blog/2640_blog_archive_part_two_a_better_url



The first thing to know is that any PHP script can be called with a URL that continues after the script filename,
eg: (these URLs don't work, they're just examples)
http://www.phase.org/journal.php can also be called with the URLs
http://www.phase.org/journal.php/journalname/stuff/things/etc
http://www.phase.org/journal.php/?id=wechsler

As far as the webserver is concerned, these are all simply requests for journal.php with 'some stuff' added on the end.

When you pass arguments to a PHP script with a query string (?key=value&key2=value2 etc), you can (as I'm sure you know) read these as $_REQUEST['key1'] etc. (You could also read them as $key1 etc, but this method is dangerous).

When you extend the URL with slashes, you can read the extra parts as $_SERVER['PATH_INFO'] (at least on Apache, I've not tested on IIS). This will give you one long string, ie:
$_SERVER['PATH_INFO']='journalname/stuff/things/etc';
You can then split this apart with
$pathparts=explode('/',$_SERVER['PATH_INFO']);
and then read $pathparts as an array - use print_r to examine it.

This now lets you avoid query strings, but you've still got a URL with ".php" in it. To get rid of this, you need to rename the script (eg to just 'journal'), but you also need to tell the webserver to treat that script as a PHP file (because it won't usually know, if the extension is missing). How to do this can vary, and you might not be able to do it if you don't have full control over your webserver.

I use the Apache directive "DefaultType application/x-httpd-php" in a .htaccess file in the directory that contains the renamed scripts.

However, even if you can't do this, you can still use directory-style access, just keep .php in the script name.

Still watching?

2005-10-10 17:59:00
Well, that last-but-one post proved to be rather more prophetic than I'd intended. Rest assured that, like 99.999% of London's population, I survived July without getting blown up. In fact, it's been another case of "too busy doing to document":

I've launched another site off this codebase: http://www.londongamelist.org/

Calendar: there's a graphical calendar view in place now, which can synchronise from iCal (and thus, indirectly, from most PDAs).

Filestore: Improvements to the upload system - in paticular fixes to handle the fact that MSIE uses some very strange mimetype declarations on file upload (image/x-png and image/pjpeg in place of image/png and image/jpeg, for example) and the ability to set icons manually (as they can't generate for Really Big images).

PHP code quality: I've turned on E_NOTICE and E_STRICT error levels on several sites using this codebase, which means I've had a fairly major task of updating code to the strict PHP5 way of doing things, and made sure all variables are pre-declared. A long task, but it should cut down on future debugging. (there are probably a few stray notices floating around this site - do let me know!)

AJAX: Many ajax tutorials advise you to use text rather than XML as your ajax page format, but also advise that you use the line
http_request.overrideMimeType('text/xml'); to force the behaviour of your XMLHttpRequest object
The new Firefox 1.5 betas throw errors on this in the (now misnamed) JavaScript Console (it now serves as a fully-fledged error console) which I've explained in updates to this page on DevMo:
http://developer.mozilla.org/en/docs/AJAX:Getting_Started
These errors can be pretty tricky to debug, particularly when they appear as JS errors...

XSS: Nasty stuff. Cross-site scripting occurs when you accidentally let a user manipulate the content of your website, either by submitted content or URL manipulation. This codebase caught most of those tricks, but at a recent talk by Rasmus Lerdorf at PHP London I discovered one that I'd completely missed: PHP_SELF. Needless to say I've done quite a few bugfixes on that one now!

MySociety: I've recently joined the MySociety group (http://www.mysociety.org/), and submitted a few code fragments - this is probably going to be a focus of my coding efforts from here, although I'll still be working on this site's codebase, particularly if there's user interest. For a start, there's a couple of external libraries that I can now jettison, due to PHP5 improvements.

I've also been to Linux World Expo, looked at picking up some LPI and MySQL certs, bought an iPod Nano (yes, they *do* scratch far too easily, Apple!) and started listening to Podcasts. Busy life.

Archive