2015: The Year of Awe

This post is over 3 years old and is probably out of date.

As 2015 comes to a close, I thought that I would jot down some words to reflect up what can only be called an incredible year.

In April I will celebrate the end of my third year as a Community Engineer Developer Evangelist, and it has been filled with more firsts that I ever thought I would experience.

January 🇺🇸✈️🇧🇪🚆🇩🇪

The year started out pretty standard with PHPBenelux (not that one could ever even suggest that PHPBenelux is anything but an extraordinary event!), but was then followed by the first of three WurstCons, which was actually a mini-tour of Germany.

Yitzchok Willroth (the [in]famous @coderabbi), Beth Tucker Long, and of course, the esteemed Jeremy Mikola and Daniel Cousineau, our organizing team, myself, as well as a host of other folks joined together for the saga that was: WurstCon EU.

ICE Train

We took the train from Brussels to Köln, where we spent two nights and visited a local Biergärten, an experience in and of itself. Here, I tried blood sausage for the first time (which some might find strange, as I am British), as well as pork knuckle.

WurstCon EU

Cologne Cathedral

From Köln, Yitz, Beth, and myself took another train to Frankfurt, while Jeremy flew to Berlin. We spent one night in Frankfurt, before Beth went off, leaving Yitz and I to carry on and meet Jeremy in Berlin.


Frankfurt Love Locks

February 🇩🇪🚆🇧🇪✈️🇺🇸✈️🇨🇦✈️🇬🇧✈️🇺🇸

After 3 days in Berlin, and 6 days total in Germany, I took the train back to Brussels for FOSDEM.

Belgian Waffle


After FOSDEM, where I got to hang out with the irrepressible PJ Hagerty and a surprise visit from Eamon Leonard, I flew back home to sunny Florida where I was greeted by the newly printed Zend PHP 5 Certification Study Guide, 3rd Edition.

Next up, was ConFoo, where I unfortunately had to rush through (one talk before lunch, one talk after, and then a flight 2 hours later…) on my way to PHPUK where I was giving my first keynote.

I cannot thank the PHPUK folks enough for allowing me to have such an amazing experience. This was a professional goal of mine for many years, and I finally realized it on a stage that, being in my home country, made it all the more special. Plus, my mum got to come!

March 🇺🇸✈️🇦🇺✈️🇺🇸

March started with me knocking another two items off my bucket-list: I made it to the Southern Hemisphere, and specifically, to Australia, for PHPAustralia. In Sydney, I got to put my feet in the other side of the Pacific Ocean for the first time, as well as see Koalas, Tasmanian Devils, Wallabies, and even take a Quokka selfie with Jordi Boggiano at Taronga Zoo.

Koala at Taronga Zoo

I saw the Sydney Opera House and the Sydney Harbor Bridge, another bucket list item (the Opera House is much smaller than I thought!), and the Three Sisters.


I even ate Kangaroo (both in Kebab, and steak form, very yummy!), as well as Crocodile (tasted like salt water…).

Kangaroo Two Ways

Most importantly, I met some amazing new people, like Jack Skinner, and my long-ago co-author, Ben Dechrai. These folks in particular are doing amazing things for the tech communities in Sydney and Melbourne (respectively). I also met the fantastic Katie McLaughlin who taught me that we all need a place to hang our hats.

April 🇺🇸✈️🇺🇸✈️🇺🇸

Following on from my longest trip to date, I then took one of the shortest, in what was my least busy month of the year, to one of my favorite conferences, Lone Star PHP. Once again, Lone Star delivered, and I have the nice comfy t-shirt to prove it. I also experienced my first Tornado Siren. That was not on my bucket list.

We also enjoyed one of the best outings for PHP Karaoke for the year. I think this picture from Ben Ramsey captures it pretty well:

I also saw this great talk by Heather White on Teaching, which changed the way I do my slides and I’ve been getting compliments ever since: Thanks Heather!

On the way home from Lone Star, I actually ditched my checked luggage in Atlanta and went to hang out at my first RailsConf, and in fact, my first Ruby-related conference. I had a great time, met some great people, and got to hang out with PJ again. Oh yeah, and Phil Sturgeon turned up too. More karaoke happened.

RailsConf Badge

May 🇺🇸✈️🇮🇹🚆🇮🇹🚆🇮🇹✈️🇺🇸✈️🇺🇸

May was another month for knocking out bucket-list items, I took my wife along to Rome, Italy where we got to see the Vatican City and watch the Pope speak (neither on my bucket list, but highly recommended), I also got to see The Colosseum (the oldest item on my bucket list, I actually cried), Palatine Hill, Trevi Fountain, and much more. From here, we took a train to Venice, another bucket list item, and got to see the islands of Murano (famous for its glassware) & Burano (famous for its brightly colored painted buildings), as well as Piaza San Marco, and some beautiful sunsets and canals views.

The Food of Italy

Our final stop in Italy, was of course Verona, for phpDay, a great little conference, in a lovely town with it’s own historic arena (which is apparently older than The Colosseum), as well as Juliets House, and I got to see the old city for the first time at the speaker dinner.


From there, I headed on to Chicago, for php[tek], always a good time, and in fact, the last time it will be held in Chicago. I am excited to see what St. Louis brings to the table, and how we will ever replace Shoeless Joe’s. I think I will always remember watching The EuroVision Song Contest with a small group of people on my phone in the Club Lounge after the conference ended…

June 🇺🇸✈️🇺🇸✈️🇲🇽✈️🇺🇸✈️🇳🇱✈️🇺🇸

After a quick trip to Boston, MA, I headed down to Mexico for MagmaConf, an amazing polyglot conference that is only eclipsed by it’s location. If you ever get the chance to go, take it. I had an amazing time for my first time in Mexico (other than the port of Cozumel on a cruise, which I’m not counting) — I flew into Colima, and then, after giving a workshop, took a bus through the hills to Manzanillo on the Pacific coast. MagmaConf happens at Magma Village, a coastal resort where you share a villa with a number of other [random] folks attending the conference. I swam in 7 different pools over the 2 days of the conference, hanging out and meeting new people.

I then ended the month at the DutchPHP Conference, this was my second time there, and it turned out to be my last talk for Engine Yard. This was actually quite an emotional thing for me — after almost 4 years, I was no longer a Yardee.

My Last Audience as a Yardee

July 🇺🇸✈️🇹🇷✈️🇺🇸

But, thanks to that quick trip to Boston back in May (Cambridge, actually), I was moving on to a new gig at Akamai Technologies. I then experienced yet another first, this time, Istanbul, Turkey. This was my first experience of a country that didn’t use the Latin alphabet (except Egypt, before I could read 😋), which was quite an interesting experience, and it would not be my last time this year.

Food of Istanbul, Turkey

Istanbul was another amazing city, with so much history and culture. I got to see the underground Basilica Cistern, and sunset from Galata Tower, among other great sights, and attended another great conference, PHPKonf. This was also the first time speaking where I was translated in real time, which was fascinating.

Istanbul, Turkey

August 🇺🇸✈️🇳🇿

August was the start of my longest travel period ever. Starting with a family vacation on the 24th, I was on the road non-stop till October 9th.

Considering I started the year never having been to the Southern Hemisphere, I — much to my amazement – got to go a second time. This time, I headed to beautiful New Zealand, and while I didn’t get to see Hobbits, I did get to enjoy a lovely drive along the coast, and had a fantastic time catching up with friends new and old at the New Zealand PHP Conference.

New Zealand

September 🇳🇿✈️🇦🇺✈️🇺🇸✈️🇧🇬✈️🇿🇦

While in New Zealand, I submitted my first patch for PHP 7.0, adding a few constants to ext/curl for HTTP/2 multiplexing.

Contrary to popular belief, I did not write the patch for T_SPACESHIP in 7.0. I wrote and proposed the T_SPACESHIP against 5.6, and it was re-written independently by Andrea Faulds. She later took on the T_SPACESHIP name after finding my original patch.

P.s. it’s one of these, not a Tie-Fighter or anything else!)

From New Zealand, I headed back to Sydney for a few days, where I got to speak at the SydPHP User Group, and gave my first talk on HTTP/2, a topic that would become a major focus for me for the rest of the year (and hopefully, beyond!). Next, I headed back to the US, to Seattle for the first time, and to meet up with my wife and son, for the inaugural Pacific North West PHP, where I was once again fortunate to keynote.

Beautiful Washington State

Following the event was my second WurstCon of the year, WurstCon NW, at Pike’s Place Market, where we shut down the restaurant for our impromptu private party (thanks to the gracious staff for that!)

WurstCon NW

I enjoyed this conference a lot, and apparently enjoyed Seattle so much (especially the drive through Mt. Rainier National Park) I’m planning to move there this upcoming February where I’ll get to hang out with awesome folks like Margaret Staples and Tessa Mero.

I then flew back to Europe, to Sofia, Bulgaria, my second non-Latin language country of the year. Now, let me stop for a moment and give a special shout out to this conference, easily in my top 3 for the year. The organizers of this conference were so amazing at making the speakers feel welcome, and safe in a country where all but two of us couldn’t even read the alphabet, and the event itself was just top-notch. I absolutely have this one my must-do list next year. Also, I climbed a fricken mountain. And the group hug at the end was epic. Oh, and let’s not forget, so much food meat, including my first time eating Horse thanks to the nicest guy I know, Damiano Venturing.

Thank you to the entire crew at Site Ground, but especially Dima Peteva for being my handler, and for even translating some Cyrillic receipts via IM for expenses after I got home!

From Europe, I took my third and final trip to the Southern Hemisphere for the year for PHP South Africa.

October 🇿🇦✈️🇺🇸

PHP South Africa actually comprised of two events, the first in Johannesburg, and the second in Cape Town. Johannesburg while fantastic, couldn’t have prepared me for our 2-day stop before heading on to Cape Town: Pilanesburg.

Here I got to take another item off my bucket list: we took not one, but two safaris. Despite the bug in my room larger than my head (my wife who was on FaceTime with me at the time I discovered it — and deafened by my high pitched scream — says I’m exaggerating), and losing one of my lenses, this was one of the most amazing experiences I’ve ever had. Seeing Elephants, Rhinos, Lions, Leopards, Hippos, Antelope, Zebras, and more in the wild, was beyond words. No photo, zoo, or wildlife park can do them justice.

Pilanesburg Safari

And yet… even that didn’t compare to the majesty of seeing, and ascending Table Mountain in Cape Town. Although Jordi and Derick actually climbed the mountain, myself, Raphael Dohms and his wife Tiscilla took the cable car to the top, where we were treated to amazing views of the end of the world, and after being joined by the hikers, we enjoyed watching the sun set over the water1.

November 🇺🇸✈️🇨🇦

My final event took me back to the frozen slightly cool North, this time to Toronto for TrueNorth PHP and the final — arguably the best — WurstCon of the year, at Wvrst in downtown Toronto, where I got to split a multi-sausage meal with Margaret and Mr. WurstCon himself, Jeremy Mikola (and we were joined by a bunch of other great folks).

We started with duck, pheasant, venison, bison, and guinea fowl:

Followed by kangaroo, lamb, rabbit, wild boar, and elk :

And finally, ending with Oktoberfest (with beer), Kaas (with cheese!), and then the more traditional Bratwurst, Berkshire, and Tamworth varieties:

And of course, I participated in this work of art:

The Last Sausage

Unfortunately, I was supposed to also speak at RailsIsrael (how this event isn’t called Israils, I have no idea!) but had to cancel due to safety concerns — this also means I didn’t manage to achieve my goal of hitting every continent2.

I also started my first real RFC for PHP 7.1, adding — you guessed it — yet more HTTP/2 feature support to ext/curl, this time in the form of HTTP/2 Server Push support.

December 🇺🇸✈️🇬🇧

December is the first month this year without any travel for work, and I’m looking forward to a full month with my family, to enjoy Christmas, and reflect on the year passed.

Also: my RFC passed with flying colors!

2015 In Summary

This year, I visited 13 countries, covering 162,862 miles (262,101km) on 79 flights via 28 airports. I spent 15.5 days in the air. That’s equal to more than six and a half (6.54) times around the world, and over half way (68.2%) to the moon!

I also tried many new kinds of meat: Kangaroo, Crocodile, Horse, Kudu, Ostrich, Springbok, Guinea Fowl, Pheasant, Venison, Bison, Wild Boar, Elk, Rabbit, and Veal!


As we head into a new year, I’m looking forward to a continued focus on HTTP/2, as well as web performance at all levels of the stack. With that, I hope to attend many different events for 2016, hopefully a lot of polyglot events, but also general web development, frontend, JavaScript, Python, Ruby, and of course, PHP events.

I hope to see all of you again next year, somewhere, and I look forward to meeting new people, and learning even more than I did this year!

  1. You can see an even better time-lapse by Jordi, here 
  2. At least as far the UN 5 inhabited continents model goes! 

Catching Up With Myself

This post is over 3 years old and is probably out of date.

Prior to November 19th 2006 I was really into PHP. I tested every alpha, beta, and release candidate, I knew every new feature inside and out, and I had plans to contribute… something. I didn’t know what, but I was going to give back to the language I loved.

However, just a few weeks after the release of PHP 5.2, my first wife passed away and I pretty much dropped off the face of the Earth as far as being part of the PHP community is concerned (EartPHP?). I did my job, and very little else. I had pushed out PHAR the year before, and it went on to become part of PHP 5.3, earning me my name in the phpinfo() output — a long time goal of mine at the time — but I pretty much missed the 5.3 release. For all the drama around killing PHP 6, and the huge changes in 5.3, I just wasn’t paying much attention.

I’ve felt like I was playing catch-up to pre-November 2006 me ever since then.

Despite everything I’ve accomplished since then, I never felt like I had reached the same level I was at back then (see: Impostor Syndrome). Till now.

Last week I put my first real1 feature addition to PHP up for voting. This has been a personal triumph for me, finally getting to grips with C enough to contribute in a meaningful way.

This year I also started getting help for my depression, and a few months ago, I started on Wellbutrin. I am sure these two things are related.

Next up, I hope to continue on this trajectory by writing a brand new extension (probably around libcurl) from scratch.

For now, I just want to say:

Dear Past Me,

We did it, finally.

– Future Past Me.

Image Courtesy of Sanjib Mitra, used under a CC-BY-NC 2.0 license.

  1. By real, I mean beyond a simple bug fix, or a copy and paste + modify change. Or adding a simple operator

PHP 7 ext/mysql Shim

This post is over 3 years old and is probably out of date.

To help ease the transition from 5.6 to 7.0 I have created a simple package that acts as a shim between the newly removed ext/mysql and ext/mysqli.

I was a little hesistent to even publish this as I don’t want to encourage the continued use of potentially insecure code, however, I want people to upgrade to 7.0 and don’t want this to be the blocker.

It does require 5.6 (though it would be possible to lower that) — however I suspect that most people who are upgrading to 7.0 are either coming from 5.6 or have the native ext/mysql. The primary reason for support 5.6 is to be able to compare the test suite results against native ext/mysql.

It’s not yet production ready, but tests are coming along pretty well (PRs welcome!):

Build Status Scrutinizer Code Quality Code Coverage

Current known (and unlikely to be fixed) issues are:

  • You must prefix all calls to mysql_* with a \ (e.g. \mysql_connect()); Not sure why I thought this, but non-internal functions do fall back to the global namespace.
  • Calls to is_resource() and get_resource_type() on MySQL connections and results will fail as these are now their mysqli equivalents.
    -Some errors are now from ext/mysqli, and others are E_USER_WARNING instead of E_WARNING. Where possible, the original error messages are replicated.
  • Column lengths reported by mysql_field_len() assume latin1 charset, and will return incorrect lengths for other charsets.

You can check it out now on Github.

Image Courtesy of Egan Snow, used under a CC-BY-SA 2.0 license.

GuzzleHttp VCR

This post is over 3 years old and is probably out of date.

A few days ago I pushed out a very small library to help with testing APIs using Guzzle: dshafik/guzzlehttp-vcr.


This is a simple middleware that records a request’s response the first time it’s made in a test, and then replays it in response to requests in subsequent runs.

It does this by returning a Guzzle \GuzzleHttp\HandlerStack with either the \Dshafik\GuzzleHttp\VCRHandler middleware, or the GuzzleHttp\Handler\MockHandler added. The first will record the responses to JSON files, while the latter will be pre-loaded with those responses and will return them when requests are made.

It’s important to understand that the responses are returned in order regardless of whether it is the same request being made.

The purpose of this library is to just make it easier to create and update your tests for API clients.

Usage is simple, just call Dshafik\GuzzleHttp\VCRHandler::turnOn() passing in the storage location before running the test, and pass in the handler as a guzzle client option:

You can pass in the handler when instantiating the \GuzzleHttp\Client, or when making the individual requests — if you use the same instance for the individual requests it will re-use the same JSON file for storage, otherwise if you pass in unique instances (with unique storage files) it will create individual ones. I recommend passing in the handler to the constructor, but ensuring that you use a new instance (of the middleware, and the client) for each test.

Hopefully folks find this useful, do let me know if you do. If you have issues, please report them and pull requests are welcome!

I’ll be releasing a new Akamai library which uses dshafik/guzzlehttp-vcr next week (probably) so look out for that if you want to see it’s use in a real project.

Made for iPhone Hearing Aids (Resound Linx)

This post is over 3 years old and is probably out of date.

For those that don’t know (and I usually mention it in my talks), I am hard of hearing, and earlier this week I tweeted this:


Over the following few days it earned an astonishing amount of attention compared to what I expected (as of Aug. 1st):

MFI Hearing Aids Battery Status Tweet Stats

I figured in light of this, folks might be interested in learning a bit more about Made for iPhone (MFI) Hearing Aids.

While there are many non-MFI Bluetooth hearing aids that will pair with the iPhone, they are treated more like a bluetooth headset than an assistive listening device. This means that you can route audio to them, just like bluetooth headphones. Some support Bluetooth 4.0/BTLE, A2DP, and such what. These are pretty awesome as-is. You can pair them with any number of BT enabled devices, with no restrictions beyond technical incompatibilities.

MFI Hearing Aids on the other hand are Apple certified hearing aids that are intended to connect via Bluetooth to an iPhone, iPod Touch, or iPad device (I use an iPhone so I’ll just use that here). Due to being MFI, they integrate much more closely with the OS. Unfortunately, this bluetooth connection seems to have a proprietary handshake that disables them from connecting as generic bluetooth devices to other types of devices (this is my biggest issue).

I have the Resound Linx 961’s. I want to write a note about the cost, because it was impossible for me to find a price without seeing an audiologist: without any kind of insurance, these things run about $7400 (a pair). With my insurance, which has an agreement with a large national discount program (but not actual coverage), they were $5200. Having worn them for a year, while I was hesitant at first, these really have had a hugely noticeable difference in my life, and especially when it comes to music, which is extremely important to me.

With these, I can pipe music, videos, turn by turn directions, phone calls, and pretty much all audio directly to my ears. And while the quality isn’t the best, I now always have a way to privately listen to music on the go.

These things are tiny, as you can see below, and the batteries are standard size 312’s, which last 3-5 days. Unfortunately, no recharging here — it’s just too small.

Resound Linx 961

I say “pretty much all audio” because there are a couple of things that baffle me: No matter what, the FaceTime/FaceTime Audio outgoing dial tone always plays through the phone speaker. Inversely, the Find My iPhone locator ping plays through my hearing aids — less than useful when trying to find my iPhone in the couch! (Both of these issues are still present in iOS 9 PB 2)

This integration takes a number of forms, but it all pretty much comes down to two places:

Settings app > General > Accessibility > Hearing Aids (this option has moved down the screen in iOS 9, but it’s still there). In iOS 8 and 9 this will be where you pair the hearing aids, you cannot pair them in the general bluetooth preferences.

Additionally, you can enable access to the controls from the look screen, and turn on Hearing Aid Mode (which I don’t use, this seems to be for traditional hearing aids when using the phone).

Hearing Aid Settings Pane

Choosing my hearing aids gives me more information and settings:

Hearing Aid Detailed Settings

In particular, you can see the battery level (yes, 5 taps deep, as opposed to in the Today overlay…), the ability to choose which hearing aids I stream to, whether the volume can be adjusted independently, which preset I’m using, and the Live Listen feature (I’ll cover this in detail later).

Furthermore, in iOS 9, they added two new options, “Hearing Aids Play Ringtones” (which will make it play your incoming call ringtone) and “Audio Routing” which lets you decide where Call Audio, and Media Audio is routed by default.

Audio Routing Settings Pane

Hopefully this last setting will solve the issue I have in iOS 8 of audio jumping between my hearing aids and my car stereo which is also connected via bluetooth — sometimes they fight for control, and as you can imagine, that’s very frustrating.

The second integration point is around the triple click of the home button. A triple click will show the accessibility menu, which will include the Hearing Aids option:

Accessibility Triple Click

Choosing this option will then bring up a whole host of settings. Mostly the same as are available through the settings app, but globally available (including, optionally, on the lock screen), and in my opinion, better organized:

MFI Settings Overlay

Here we have the battery levels (triple click + tap), independent volume (regardless of the setting above) and combined volume, preset option, and again, Live Listen.

I use this screen approximately a billion times a day.


The presets are actually why I love these devices. These particular ones can have 4 different presets, and there are many to choose from (though they have to be setup by an audiologist, and they can be tweaked individually). Presets are realtime audio filters, that will enhance the audio on it’s way to my ears.

In my case, these presets are:

  • Softswitch — auto-pilot, I use this most of the time
  • Outdoor — this will cut things like wind noise, great for cycling, or walking in windy conditions (imagine getting turn by turn directions directly in your ears while cycling)
  • Restaurant — this will enhance voices, and dim things like clattering silverware, making it much easier to hear in crowded spaces
  • Music — this is my favorite, it will actually remove all filters, and let me hear just the raw audio, with the volume boosted.

If we’re having a conversation, and you see me reach behind one of my ears, or fiddle with my phone, it’s actually me trying different presets to make your voice as clear as possible in whatever situation I’m in — it’s not perfect, sometimes Outdoors is great in crowds, other times Music is the best option to be able to hear (I find that when listening to anything through a PA, Music works better).

Live Listen

Another feature, which I really don’t use, but is still pretty cool, is the Live Listen feature. This lets your iPhone act as a remote microphone. Simply place it near the person/thing you’re trying to hear, and it will stream whatever the microphone picks up directly to your hearing aids via bluetooth.


In addition to all of this, through the accompanying app, you can also change the treble and bass, as well as set geo-fences for automatically switching programs (and treble/bass) based on location.

All-in-all, I’m super glad I made the plunge to get hearing aids (again), they have had a remarkable impact on my life, and the technology packed into these things is crazy. They’re almost invisible, and I’ve had many people say they would like the abilities of these even if they have good hearing!

I hope this post shows you just how cool we’ve come with the technology, and that if you have avoided them till now that you consider getting something like this.

I also evaluated the Resound Linx 700-series, and the Starkey Halo. I settled on these as having the best features and app.

However: while looking stuff up for this post, I came across the Kirkland Signature™ Hearing Aid at CostCo, which looks to be the same device branded under another name. These run just $1799 a pair! I was also reminded that there is an additional piece of hardware to allow generic bluetooth connections, as well as connecting to things like TVs and streaming to the hearing aids.

An Exceptional Change in PHP 7.0

This post is over 3 years old and is probably out of date.

With PHP 7 errors and exceptions are undergoing major changes. For the first time, the PHP engine will start to emit exceptions instead of standard PHP errors for (previously) fatal, and catchable fatal errors. This means that we can now handle them much more gracefully with try... catch.

But with this change, comes a whole new exception hierarchy:

At the top we now have an interface, \Throwable, which the original \Exception implements. Earlier versions did not have the interface and the root of the hierarchy was \Exception. We then have the new \Error exception, which is a sibling of \Exception as opposed to extending it, which also implements the new interface.

The reason \Error does not extend \Exception is so that the new exceptions will not get accidentally caught by legacy catch-all statements (catch (\Exception $e) { }) — and just like in older PHP versions, an uncaught exception is still a regular fatal error, preserving backwards compatibility.

If the ability to create a real catch-all is desired, you can catch the \Throwable interface. This means that to catch both regular exceptions, and engine exceptions, you would use catch (\Throwable $e) { } instead.

Error Exceptions

As you can see above, there are four new error exceptions, each one used for a different purpose:


Standard PHP fatal, and catchable-fatal are now thrown as \Error exceptions. These will continue to cause a “traditional” fatal error if they are uncaught.


With PHP 7, we also have enhancements to assertions, using the assert() function, with the addition of zero-cost assertions, and the ability to have them throw exceptions. To enable this, you should simply set assert.exception to 1 in your php.ini (or via ini_set()).

These exceptions are (you guessed it) \AssertionError exceptions.


Thanks to error exceptions, you can now handle includes with parse errors, and eval() parse errors, as both now throw \ParseError exceptions:


With the introduction of scalar, and (especially) strict types in PHP 7, these will also throw exceptions when a type mis-match occurs. It is important to understand that this does not apply only to scalar type hints, but to traditional type hints such as class/interface names, callable and array.

Catchable Fatal Errors

Another important change in PHP 7 is with catchable fatal errors. Previously, these would have been caught and handled using set_error_handler(). However, with PHP 7, they are now \Error exceptions, which, because an uncaught exception is now a real fatal error, will no-longer be catchable in set_error_handler().

This is a backwards compatibility break and means that to work in both PHP 5.x and 7, you need to use both set_error_handler() and try... catch.

This is considered a minor BC break due to limited usage.

\Throwable and Userland

It would not be a big jump to conclude that now we have a common interface, we could create our own branches in the exception hierarchy for completely custom exceptions by simply implementing the \Throwable interface. Unfortunately, due to the fact that exceptions are magical under the hood, to be able to do things like capture line/file and stack trace information — this means that you still must still extend either \Exception or \Error, and cannot directly implement \Throwable alone.

Trying to implement \Throwable results in the following:

However, this is not the full story. You can extend \Throwable and then — while still extending \Error or \Exception — you can implement your extended interface:


As alluded to in the (pun intended) title of this post, these changes are actually quite big, allowing us to gracefully handle almost all previously fatal errors. The fact that the core team were able to maintain almost complete backwards compatibility while doing so is astounding. Kudos to them!

Class constants, how do they work? (Or: You Learn Something New Every Day…)

This post is over 3 years old and is probably out of date.

Yesterday on Twitter there was a conversation started by Marco Pivetta regarding a particularly horrible bit of code he had spotted:

If it’s unclear, this creates a string using sprintf() by prefixing ::PARAMNAME with the result of calling get_class() on the $api variable, and then passes that string into constant() which will give you the value of a constant using it’s string name.

At which point Elizabeth Smith chimed in to point out that $api::PARAMNAME would not work in older versions of PHP, necessitating this horrible workaround.

I then added this to the conversation:


Turns out, I was wrong. Whoops. Trevor Suarez created a past on 3v4l.org showing that this did indeed work, going back to PHP 5.3 even.

Additionally, with PHP 7 — thanks to Uniform Variable Syntax — there are many more ways to achieve this too, as you can see below:

Now, obviously, a lot of these are facetious, I mean, who is going to do ['Foo'][0]::BAR, really? But it’s interesting to see just how consistent, and flexible the new Uniform Variable Syntax is.

The someFunction()::CONSTANT, SomeClass::method()::CONSTANT, and $obj->method()::CONSTANT are much more realistic, and likely to be something you will use at some point.

There were a few syntaxes that didn’t work, which on the one hand, I’m grateful for, but on the other, I think at least some of them should be possible. Presented without further comment:

As with everything in any programming language however:

just because you can do something, doesn’t mean you should

Use with caution.

Changes to Engine Exceptions in PHP 7.0alpha2+

This post is over 3 years old and is probably out of date.

Pre-Release Software

This blog post is about PHP 7.0 which at the time of writing is currently pre-release software (7.0.0alpha2) and subject to change.

While updating my PHP 7 talk “What to Expect When You’re Expecting: PHP 7” for the DutchPHP Conference 2 weeks ago I noticed a small but significant change to the new Engine Exceptions feature in the newly release alpha 2.

Prior to alpha 2 and as per the Engine Exceptions RFC the exception hierarchy looked like this:

BaseException (abstract)
 ├── Exception extends BaseException
      ├── ErrorException extends Exception
      └── RuntimeException extends Exception
 └── EngineException extends BaseException
      ├── TypeException extends EngineException
      ├── ParseException extends EngineException
      └── AssertionError extends EngineException

The primary reason for doing this was to ensure two things:

  1. That \EngineException‘s didn’t get caught in pre-.7.0 catch-all blocks (i.e. catch (\Exception $e) { } to preserve backwards compatible behavior (fatal erroring appropriately
  2. That it was possible to build new catch-all blocks for all both old and new exceptions using catch \BaseException $e) { }

However, for alpha2 this hierarchy changed. Engine Exceptions lost their “Exception” suffix, and became \Error and and \*Error exceptions, and the abstract \BaseException class was changed to a \Throwable interface. This makes the new exception hierarchy look like this:

Throwable interface
 ├── Exception implements Throwable
      ├── ErrorException extends Exception
      └── RuntimeException extends Exception
 └── Error implements Throwable
      ├── TypeError extends Error
      ├── ParseError extends Error
      └── AssertionError extends Error

With these changes, you still cannot create your own exception hierarchy as you cannot implement \Throwable, you must still extend from \Exception or \Error exceptions (or their children), however you can extend \Throwable and (while still extending \Exception or \Error) implement that new interface.

Personally, I prefer this hierarchy, but, as with any pre-release software: everything is subject to change!

As pointed out to me on Twitter, there is an RFC for this change: Throwable interface RFC

Farewell Engine Yard!

This post is over 3 years old and is probably out of date.

After almost 4 years at Engine Yard, my last day will be July 3rd.

It is a sad thing, but it also means I am moving on to hopefully bigger, exciting, more challenging, and better things.

On Saturday I gave my last conference talk as a Yardee, and I think it was fitting that it was about “What’s new in PHP 7”, as my first talk for Engine Yard was at PHPUK 2012 and it was about “What’s new in PHP 5.4”.

I have had an amazing time working for Engine Yard, learned a lot from lots of smart people, been able to travel the world and meet even more fabulous people. I have been allowed to shape my job around the life I want to lead: to be a good person, to teach and help people, and to spread the joy of the things I love to as many people as possible.

I will be moving on to Akamai Technologies on July 6th as a Developer Evangelist.

I will be working on some thing bigger than I can conceive and I’m excited at the prospect of helping people — particularly in the PHP community — to achieve amazing things using these tools and more.

But I wouldn’t be here if not for all I’ve been enabled to do the last four years:

Thank you Engine Yard ❤️

Y’all should go check out Deis and Deis.com/Deis PRO, they’re pretty awesome!