Unit testing headers in PHP

There's plenty of questions about unit testing code that sets headers using PHPUnit. PHPUnit officially assumes that neither the test code nor the tested code emit output or send headers:

(from https://github.com/sebastianbergmann/phpunit/issues/720#issuecomment-10399612)

And rightfully so. Headers are essentially global state, which is hard to unit test. However, if you're willing to install the PECL extension Runkit, you can actually unit test headers if you really want to.

I use the setupBeforeClass hook to only run the code once before the entire class runs. If you only have one method that you're testing it can all get stuck in the single test. I check if the runkit extension is loaded to avoid breaking the unit test suite if someone tries to run it that doesn't have runkit installed. The test that actually looks at the headers is marked with a requires annotation, which will mark that test as skipped if runkit isn't loaded. If every test in your test class tests headers, you can move that up to the class level if you'd like. My particular class had some tests that didn't need runkit and I wanted those to still run for people that didn't have runkit loaded.


Public key crypto

I recently received an invite for keybase.io. For those of you that haven't looked into it, it boils down to a public repository of public keys attached to certain geeky identities (Github and Twitter, for now). It's a new way to build a web of trust.

Where keybase.io shines

It is easy (relatively speaking) to install the tools and create your identity. It's easy (again, relatively speaking) to verify your identity on the two public sites that they've picked for verification. The UI is much prettier than the open keyservers that we already had. For example, keyserver.ubuntu.com is obviously written by geeks, for geeks as is pgp.mit.edu.

It's easy enough to invite your friends (if you have invites, that is) and publicly track them.

The most important piece that Keybase brings to the table is some minimal verification. With the public keyservers, you generate a key attached to an email address, then upload it to a keyserver. There's nothing that verifies that you actually own that address. With Keybase you've got a key attached to an email address and to a Twitter account and a Github account.

Where keybase.io fails

Unfortunately, this is a longer list.

It is relatively easy to install. It is far from easy. It requires command line access and node installed, which is far from trivial for non-geeks.

They don't really tell you what tracking means. When you track someone, you're saying that you vouch for their identity. There are plenty of people that I "know" on Twitter that I've never met in real life. They may or may not be who I think they are.

They encourage you to upload your private key to their server. You should never give your private key out to anyone, no matter how much you may trust them. They make a big deal about how they encrypt it and never see it, but you're expected to just trust them. They seem on the level, but for all that I know they're nothing more than a front for the NSA to get your private keys.

Once you've connected with others and verified their identity, what then? For most people, cryptography is another step in the way of communicating with people. I doubt Keybase will convince many people to start encrypting their communications. Hopefully it will at least convince people to start signing their git commits. But without a plugin for Gmail and Outlook, I doubt many people will even be bothered to sign their emails, much less encrypt them.

While it's easy enough to connect to people you know once you find them, it's not particularly easy to find them in the first place. This might be just because it is still in alpha. Hopefully they'll allow you to search your Twitter friends. Seems like an oversight since Twitter is one of the ways to verify your identity.

Overall thoughts

I doubt Keybase will ever fully replace the existing public key infrastructure. It's pretty easy to verify identities there, but there's not much value-add over a prettier front end to the existing solutions. I hope there's a lot more to come as it leaves alpha.

That being said I really hope that it takes off in a big way. Our email may be sent in the clear and stored in the clear. It was never really designed to avoid being read by third parties. Hopefully recent disclosures about the NSA make people realize that their communications are not safe. If just one more person protects their communications from spying, Keybase will have been a success in my eyes.


Midwest PHP 2014 wrap up

Midwest PHPLet's get the negative stuff out of the way first. It was cold. Like, really cold. And I'm a wimp when it comes to the cold.

Whew. Thanks for struggling through all of that. With that out of the way, let's talk about how awesome the conference was. This was the second year I was invited to speak, so I'll also do some comparing with 2013's conference.

Location, location, location

They moved into the city to a bigger college. It was a big improvement over last year's venue. The rooms were big enough for the audience and had plenty of power in the two smaller rooms. I only heard one speaker mention having A/V trouble: two sets of dead batteries for the microphone. I had a bit of trouble figuring out which building the conference was in, but once I did, it was easy to get from session to session.

The food was pretty good as well, with soft tacos the first day and sandwiches the second. They took good care of those with special dietary needs as well.

The after party's location was very intimate, and really helped to mix up the speakers and attendees, which I feel very strongly about. I talked to every single person at the after party except for the people sitting down around the edges.

Content is king

The worst talk that I saw was still very interesting to me. The selection of speakers was fantastic in both breadth of topics and depth of knowledge. The only knock I have on the list of speakers is that it's pretty much the same group of speakers you see at other conferences such as SkiPHP and Lone Star PHP. The community really wants you (yes, you) to start speaking at your local user group and then at conferences. Trust me, you've got some knowledge worth sharing and can do this. 

And for some reason, I spoke as well. Despite my fear of public speaking and my nerves almost derailing my talk, it went over very well. The attendees were very welcoming and friendly.

Conferences can be so humbling to see the amazing stuff that people are doing and willing to share with you. Many of the speakers literally wrote the book on their topic. You can see them talk about it, and then chat with them about it more afterwards. That's just amazing to me.

The Atmosphere

Wow. So energy. Much connections.

The attendees were a friendly bunch, and the hallway track seemed to be on fire. The IRC back channel was very talkative, owing to some well-timed tweets to get new people on to Freenode to join the conversation that.

Overall Impression

I really hope that certain non-MidwestPHP events don't conspire to keep me from being able to submit a talk to Midwest PHP 2015. I really like this conference, the people, and the experience and would love to come back next year.


Coding for easier and quicker code reviews

If your company doesn't do code reviews, you most certainly should. If you're bound and determined to ship crappy software by not doing reviews, this post won't do much for you.

Code is meant to be read

Many people are under the mistaken impression that their code is meant for the computer's consumption. While it's true that a computer will consume your code, it is not who you're writing for. Programmers are your intended audience. That includes you. Coding a new project is the easy and short part of the software's lifecycle compared to the time code spends in the maintenance and upkeep phase.

So, assuming that you want to write code that's easier to read as well as easier to review, here's a few tips. All of them come from dealing with real coworkers. If you've worked with me and recognize something that you still do, you should feel bad. You're probably the reason I wrote this.

Descriptive variable names

Yeah, that's just good software development practice, but it can really help during code reviews as well. A short variable name that doesn't describe what it does is much harder to figure out during a code review since most review tools (at least that I've used) don't give a huge amount of context around the change. So while someone going in to edit the code might quickly figure out what the variable is supposed to contain, a reviewer has to dig.

Exceptions: Obviously loop control variables should be short ($i, $j, $k) as well as variables that use a single letter commonly, like representing coordinates ($x, $y, $z).

Useless commit messages

"Fixed a bug" or "Made change suggested in review #1234" are nearly useless. While they may be factually correct, they don't really tell the review what and why you're changing something. In the first case, the reviewer has to figure out what the bug was before they can decide that you've fixed it (and fixed it in the best way). In the second case, they have to go back to the original review to figure out what the suggested change was (and whether it was a good idea in the first place) before they can determine whether you'd fix the original problem.

Exceptions: If you've got a code sniffer (PHPCS, for example) that complains about things, having a commit message of "PHPCS" is plenty clear that you're appeasing PHPCS.

Trailing commas

This one is a bit controversial, especially if you frequently switch between PHP and javascript. PHP allows trailing commas for arrays while certain paste-eating browsers don't allow it in their javascript parsers. Creating an array with the trailing comma makes later reviews easy to read. For example, if you have an array like:

    $letters = array(

and you need to add a new letter:

    $letters = array(

code review packages will show two changed lines:

    $letters = array(

If you always include the trailing comma it makes it obvious during the review that you're only intending to add a new element. This is a trivial example, but it helps to show your change's intent better, which helps a reviewer better understand what you're doing.

Code reviews are meant to help you

Don't get your feelings hurt when someone points out mistakes that you've made. Everyone is trying to get better. If you send shorter review requests that are easy to read, it's much more likely that you'll get responses quickly and with less confusion.


Conference speakers, come out of your towers

I'm not a great speaker. Heck, out of the hundred or so that I've seen since I started speaking at conferences I'm not sure I would even rate myself in the top 80. But I have noticed a few things that speakers could do to improve the conference experience for both attendees and speakers. After all, conferences are (well, they should be) about the attendees, not the speakers.

Most speakers do a pretty good job of interacting with attendees that come up and talk to the after their session, or in the hallway track later. But that's about all of the interaction the general public gets.

That's not enough.

Many speakers are friends. They may be friends that only hang out with each other at conferences, but they look forward to seeing each other. They may have not seen each other since the previous conference, so they understandably want to catch up. So they sit together at meals, they group together in other sessions, and disappear into the speakers' lounge to talk privately.

That robs attendees of the chance to get access to you. The speakers' dinner, which most conferences have, is your chance to catch up. The rest of the time, speakers should work to make themselves available to attendees.

I pick random tables at lunch to sit at. The conversations are almost always as interesting as the ones going on at the speakers' tables (if not more so), but with new people.


SkiPHP Wrap Up

The last weekend was the first year for another regional PHP conference called SkiPHP. Similar in many ways to other regional conference that I've attended (Lone Star PHP and Midwest PHP), SkiPHP was a fantastic opportunity for people local to the Salt Lake City area to attend a conference without having to miss (much) time from work for travel.

The speakers were typical for such an event, with a few new speakers sprinkled in among a subset of the typical PHP speakers. People from the PHP community looking to make the jump from speaking at user groups have a very good opportunity to speak at conferences such as these, and I encourage all of them to submit proposals. See what conferences have open CFPs at callingallpapers.com/.

The Venue

The conference was held at a college. This came with both some good points and some bad points. First, the rooms were all equipped with AV equipment that worked just fine. I didn't hear about any problems with the equipment, with the lone exception of a static-prone wireless mic.

The three smaller rooms had plenty of seats and tables. They were classrooms after all. Depending on the time of day, one of the rooms did have a problem with the sun causing glare on the screen, but the speaker and attendees were able to soldier through that without too much problem. They also didn't have much in the way of power outlets. My fancy power outlet came in very useful several times throughout the day.

The larger room was a lecture hall. I'm really glad I didn't have to speak in that room. It was set up for a professor to stand behind a podium and lecture, which none of the speakers that I watched in that room had any interest in doing. All of them wanted to get out from behind that thing, which I applaud. There really wasn't anywhere else that speakers could put their laptops and still interact with them for speaker notes and advancing slides.

The Talks

All of the talks I saw were fantastic. I made it a point to see some speakers that I had never seen before, and checked out some talks that were on subjects that I was very unfamiliar with. The only exception was the keynote, which was an updated version of the talk that Laura gave at Lone Star PHP 2013.

Unfortunately, looking through the joind.in pages for the talks, some of the speakers, especially the new ones, haven't claimed their talks, which makes me think that they're missing out on some of the feedback that people gave them. That's really important!

The Atmosphere

Overall, it was a much more focused conference. Many of the conferences that I've been to in the past were about making connections with other geeks and feeding off the combined energy of a room full of geeks to recharge your developer batteries first, and learning new things was cool too. Very few of the people that I talked to in the halls or at lunch seemed at all interested in connecting outside or after the conference. Perhaps I was just to brash for the average SkiPHP attendee.

Overall Impression

SkiPHP was a very well-run conference that I would recommend to anyone from the area. If I can fit it into my company's new stricter conference attendance policies, I will definitely try to return next year and hopefully hit the slopes while I'm there.


Keezer build

I like beer. I like brewing beer. But I don't like having to bottle my beer. I also like draft beer, but don't have any way of getting draft beer at home so that I never have to venture out into the outside world.

I could just keg my beer one five gallon batch at a time, but my philosophy is that if it's worth doing it's worth overdoing. So I'm building a five keg system.

The freezer came from Home Depot. I normally don't do business with them because of their shady credit practices, but the deal was too good to pass up. The temperature controller was ordered from Amazon.com. Most of the other hardware came from Midwest Supplies, I spend way more money with them than I probably should. The CO2 tank and the Sanke tap were purchased from Kegs & Barrels. Paint and wood were purchased from Lowes. My first commercial keg came from Choice Beverage in McKinney.

Parts list

The Build

Here's the freezer before it gets completely repurposed:

Cutting the wood with Jason's help:

Attaching some 90 degree brackets and cutting the insulation:

Drilling the one inch holes for the shanks:

Installing the shanks:

Attaching the back to the side:

Altogether now:

Attaching the gas distributor:

Backside of the installed shanks:

Faucets installed (Midwest backordered one of the shanks):

Wiring up the temperature controller:

Semi-finished product, I thought it was meant for me, but Scriptlet thinks it made a good bed. I had to take off the hinges. I'll add them back with another set at some point:

Inside after adding kegs and stuff. That's a keg of Omni's Hardly Workin' Ale and Lakewood's Temptress. There's also a fermenter with a batch of Omni's Employment Anchor Away

Future improvements:

  • Resizing the collar. I didn't cut it to the right size, so it's too deep. Apparently I suck at math. I blame imperial units and the American education system.
  • Painting the whole thing very dark brown to match my office's furniture.
  • Installing the last shank when it arrives.
  • Mounting the temperature controller and a thermometer so I can see what's going on in there better and control it.
  • Installing a drip pan.
  • Adding more gas line. I bought pre-built gas lines from Midwest, but had to take two of them apart. One goes from the CO2 tank to the distributor, and one goes to the commercial Sanke tap. 
  • Installing hinges. The lid will be hinged as well as the collar.
  • Tracking system to show the beers on tap as well as how much of each is available.