Over the weekend, I released v1.5.1 of HubFlow – a Git extension that brings the gitflow workflow to GitHub.
The key new features are:
- New ‘git hf push’ and ‘git hf pull’ commands, which do the right thing no matter which kind of branch you’re working in at the time.
- No more manual ‘git remote update’ before running HubFlow commands.
There’s also a long list of smaller changes and fixes too – many thanks to everyone who sent in a pull request or logged an issue.
The full ChangeLog is available.
I’m starting to get requests for documentation and portability fixes for Windows users. I don’t run Windows on any of my computers, so if there’s anyone out there who’d be interested in helping out, please let me know!
Comments Off
I’ve mixed feelings about the PSR standards to date.
- PSR-0 has standardised autoloading in a practical way. Sure, it does have an evil design flaw (different classes can map to the same file on disk), but in practice it’s not a problem that happens.
- I’d have personally liked to have seen PSR-1 go further, and address method naming in more detail (in particular, that method names should start with a verb), and also address getters/setters and protected vs private.
- I’ve no personal interest in PSR-2, and am philosophically against “layout” coding standards like this.
… so I wasn’t sure what to expect when I decided to add PSR-3 support to a private framework I use to build test tools at DataSift.
What Is PSR-3?
PSR-3 is a proposed standard (voting has finished, it should appear as an accepted standard when the PSR folks recover from too much Christmas turkey) describing a common logging interface for PHP frameworks.
It’s based on a small subsection of RFC 5424, which describes the Syslog standard, which is a very sensible choice. Sysadmins think in terms of Syslog levels, and they utterly hate dealing with loggers that don’t map cleanly onto Syslog.
What Does The Interface Look Like?
To support PSR-3, you’re required to implement the following methods:
- emergency($message, $context = array())
- alert($message, $context = array())
- critical($message, $context = array())
- error($message, $context = array())
- warning($message, $context = array())
- notice($message, $context = array())
- info($message, $context = array())
- debug($message, $context = array())
- log($logLevel, $message, $context = array())
You can see the proposed interface in full here, including the constants for $logLevel.
The $context is a list of named parameters to substitute into the $message. The special parameter ‘exception’ is reserved for an exception that needs to be added to the logs.
A Critique of PSR-3
PSR-3 is built on a good idea, but there’s three areas where I think PSR-3 could have been better:
- the method names in the LoggerInterface
- the handling of the exception parameter
- the LogLevel constants
I’d have also liked to have seen trace level logging supported, although I can understand why most PHP developers won’t be aware of that practice.
Better Method Names
It’s perhaps a small thing, but I’m a big fan of making code more readable by having all method names start with a verb. I find that it makes code more self-descriptive, and that it’s much easier for casual contributors to grok.
So, instead of this:
- $logger->emergency(“Captain, she canna take no more”);
we could instead have had:
- $logger->logEmergency(“Captain, she canna take no more”);
Like I say, a small thing, but in my experience it’s improving all of the small things that leads to big successes, especially in larger code bases.
Handling The Exception Parameter Properly
To paraphrase, the PSR-3 standard says this about the $context parameter: “here’s a list of key/value parameters, but one is special”. That “but” is a code smell!
Not being able to treat all of the key/value parameters equally (slightly) increases the complexity of handling $context, increases the performance cost of logging, and forces the Logger implementation to do things that PHP could handle for us.
A better solution would be to move the exception out of the $context and make it a separate parameter like this:
- logEmergency($message, $context = array(), Exception $cause = null)
This would allow PHP to make sure that only a genuine Exception was passed into the log method, and would allow the implementation to treat all of the key/value pairs in $context equally. This is a cleaner interface to implement.
Log-Level Constants
RFC 5424 defines the log levels as an ordered set of integers. This is deliberate, as it makes it trivial to say “only log warnings and above”. Unfortunately, because it was difficult to crowbar this into Monolog, the decision was taken to go with strings for the log-level constants. This regrettably increases the complexity of all other loggers.
If you look at pull-request to add PSR-3 to Monolog, you’ll notice that Monolog is explicitly relying on the value of the PSR-3 constants to map them directly onto Monolog class constants:
375 + public function log($level, $message, array $context = array())
376 + {
377 + if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) {
378 + $level = constant(__CLASS__.'::'.strtoupper($level));
379 + }
380 +
381 + return $this->addRecord($level, $message, $context);
382 + }
This is done because (ironically) Monolog already uses numerical log levels internally, with the debug level having a value of 100, and the emergency level having the value of 600. There was obviously the risk of Monolog log level constants being passed in instead of the PSR-3 constants, where it would have been impossible to tell them apart if they were both numeric. I’m sure other existing loggers probably face similar issues.
It’s a tricky issue, but on balance I think the wrong decision was made here for the wrong reason, and the community would have been better served longer-term if PSR-3 had supported the RFC 5424 values for the log level constants.
Final Thoughts
PSR-3 isn’t objectionable … it’s just that it could have been a bit better than it is.
I’ve added both PSR-3 support and the revised methods from this blog post to my internal LogLib. PSR-3 will allow me to inject LogLib into third-party components that support it. My own code will be using the revised methods I’ve proposed here, for the reasons mentioned above.
Comments Off
From the Introduction:
“This e-book will hopefully show you how to put yourself across to a prospective employer in a way that makes it easy for them to spot what you have to offer them, to increases your chances of successfully finding a job in the United Kingdom’s computing industry.
“Recruitment processes vary from employer to employer. I’ll take you through the most likely steps that you need to get through. I’ll explain the process from the employer’s perspective first, and then from your point of view as someone applying for a job. A better understanding of what the recruitment process is, and why, will help you avoid the common pitfalls along the way.
“The second part of the book is more about you, about what you need to do to be prepared for when you join the industry, either during an industrial placement year or when you graduate and leave academia. Ours is a multi-disciplined industry where things change rapidly, so to help you prepare, I’ve finished off the book with some lists of the fundamental skills that industry expects you to have before you start your first job.”
Getting Hired is a free ebook released under a Creative Commons licence. I hope you find it useful.
2 comments »
Last weekend saw the PHP NorthWest user group run their fifth conference. Spread over three days, it gave over 400 folks who attended great talks on a wide variety of topics from speakers both established and new. Once again, Jeremy, Rick et al ran an excellent conference, and I’m already looking forward to next year’s event.

See more of my photos from the PHPNW12 conference on Flickr.
Comments Off