MacBook Pro Retina 3.5mm TRRS Cable With Audio Input

One of the unexpected surprises that came with upgrading to a new Macbook Pro Retina 15″ from an older MacBook Pro was Apple’s inexplicable deletion of the audio input (mic) 3.5mm jack. I use a regularly use a gaming headset with a boom mic that was now rendered completely useless, because I was no longer able to plug in the mic. I love it that Apple’s hardware is on the cutting edge, but sometimes they do things like this that just don’t make sense for the average user.

What Happened?

I did some searching around, and discovered that Apple changed the standard dual input/output 3.5mm jacks for a single combined TRRS 3.5mm jack with 3 contacts – the same one they use for the iPod, iPhone, and iPad. I guess it makes sense for Apple to standardize everything so you can use their headphones everywhere, but it caught me offguard and really frustrated me that I would have to buy something extra just to continue using my headset.

Where did the mic jack go!?

Things I Tried

I did some searching and originally purchased this Headset Buddy cable from Amazon. It’s $15.95(!) and has branding from the 1980’s. I cringed and made the purchase thinking it would be worth it if it solved my problem. When it arrived, it was clear that the price of the cable is about 3x what it should be. The cable is flimsy and cheap, and didn’t even work at all. I promptly returned it. The customer reviews are mixed, but don’t gamble on it.

That cable purchase has soured my view on the TRRS splitters for a while, so I opted for a USB audio adapter to 3.5mm input/output jacks instead. It was a little cheaper at $10.95 and worked great, but came with a huge downside: It uses one of only TWO total USB ports on your MacBook Pro – a precious resource that I was already using (and thus had to also use a USB hub). Another downside here is that you have to explicitly switch to USB audio using the Sound preference pane, which can be annoying at times.

The Best Solution

The best working solution (and also the cheapest) I found is this TRRS audio cable from Monoprice for about $5. When it came in the mail, I originally thought I ordered the wrong cable, because the configuration is weird. Instead of a typical “Y” configuration off the male jack, it instead splits off from the 3.5mm audio input female jack into another 3.5mm audio output female jack. Make sure you look at all the product images to see what I mean.

Weird Cable Configuration

The cable works well and feels very durable, even if it does looks like the wrong type of cable (Monoprice, if you’re listening – please fix this. It works, but it just looks weird with the “Y” coming off the female 3.5mm input jack).


Hopefully my misadventures in trying to solve this problem that Apple itself doesn’t even have a cable for will help you not have to do all this experimentation yourself. I feel like this should have been way easier than it was to find a cable that works on newer Macbook Pros, but apparently marketing lags a bit behind for 3rd party accessories like this (all these cables are marketed as iPod/iPhone/iPad cables, which have the same TRRS 3.5mm jack). In another year or two, I doubt this will be a problem at all, but just incase it still is – you can always find this blog post :).

UPDATE (March 13, 2017): At some point after about a year and a half, the TRRS cable I recommend in this article from Monoprice stopped working. I ended up just buying and using a new USB gaming headset instead. I know that’s not the conclusion you want to hear, but it is the unfortunate truth. In my particular setup with an external monitor with built-in USB hub it is not too much of an issue since it doesn’t use an extra USB port that way, but your mileage (and USB port utilization) may vary.

Oklahoma PHP User Group Reboot

Our first Oklahoma PHP User Group meeting in a few years happened on Thursday, February 20th 2014, thanks to the efforts of Jake A. Smith who contacted me about it (as I ran the previous PHPUG a few years ago) and did all the legwork to make it happen. We are now going to co-organize the user group going forward.

After a meet & greet fueled by pizza and soda, I presented a short introductory talk on Composer, which also covered using and publishing packages to Packagist. The turnout was fairly small – around 12 people or so, but everyone was excited that the user group was happening, and there were lots of beginners and new faces.

Our meetings are going to be on the 3rd Thursday of each month. All our meeting times, descriptions, etc. will be posted on our Meetup Page. Our March plans are tentative, but we plan to do a PHP Foundations talk that will cover all the basics like Namespaces, PHP-FIG standards, code organization, etc. so it should be a great meeting for begineers and those who are not familiar with what the larger PHP community is doing. You can RSVP on the Meetup page to get notifications and reminder emails for upcoming meetings. Hope to see you there!

Using Dokku to Deploy PHP Applications with a “git push” on DigitalOcean

Want a Platform-as-a-Service setup like Heroku on your own $5/month VPS from DigitalOcean? Look no further than Dokku

  • a set of scripts built on Docker and Heroku’s own buildpacks. After this setup, you’re just one git push away from deploying your app to your own server.

Step 1: Create a new Droplet with Dokku

DigitalOcean has a great guide on how to use the DigitalOcean Dokku Application, so there is no sense in repeating the steps here. Follow the steps in that article, and then come back here. There are issues I ran into after the Dokku setup that are important steps not to skip. So be sure to come back here before trying to deploy your PHP application.

Step 2: Setup Swap Space

DigitalOcean boxes don’t come with any disk swap space configured by default, but Dokku uses some when deploying your apps, so you need to configure some using this guide before your first git push or you may run into errors (I sure did). The guide says Ubuntu 12.04, but it works on 13.04 too, so no worries. Do this and then come back. I’ll wait.

Step 3: Deploy Your App

Although the setup is not fully complete, try and deploy your app now to make sure your dokku setup is working properly. You also need to deploy your app now so you will have a container ready for the next steps.

git remote add dokku
git push dokku master

The ouput of the git push will let you know if your deploy was successful or not. If you have a successful deploy, but get a “502 Bad Gateway” response from Nginx, continue with the steps below.

Step 4: Install the user-env-compile Plugin

Install the user-env-compile plugin. This will allow you to set environment variables on your app that are available to be used at build time. This is important for the next step.

Step 5: Use CHH’s PHP Buildpack

Now that you have the user-env-compile plugin installed and have created your app’s initial container, you can set environment variable configuration values on it. To specify what buildpack you want to use, set the BUILDPACK_URL ENV value.

ssh dokku@<> config:set <app_name> BUILDPACK_URL=

You should see output like this:

-----> Setting config vars and restarting <app_name> BUILDPACK_URL:
-----> Releasing <app_name> ...
-----> Release complete!
-----> Deploying <app_name> ...
-----> Deploy complete!

NOTE: ANY Heroku buildpack will work, so if you want to use another one, you are free to do so, although it is very doubtful you will find a better one for PHP :).

Step 6: Set your Document Root

Now open your composer.json file, and add the extra configuration block to specify your document-root and index-document so the PHP buildpack will know where to serve your files from.

     "require": {
         "php": ">=5.4.0",
         "vlucas/bulletphp": "~1.3.x"
     "extra": {
         "heroku": {
             "framework": "slim",
             "document-root": "web",
             "index-document": "index.php"

Note: The framework key here is slim. This doesn’t match my framework Bullet, but I have to put this in here because this maps to the nginx config file used. So if I don’t specify this here, the buildpack assumes a standard classic PHP setup and will only execute .php files, and not rewrite all requests to the main index.php file like most frameworks (including Bullet) require, causing nginx to throw lots of “404 error” responses.

The configuration key says heroku, but this works for dokku too – remember Dokku basically uses all the same basic things that Heroku does – buildpacks, git based deploys, putting apps in their own sandboxed containers, etc.

Step 7: Install Other Plugins Your App Needs

Custom Domains

You will want the dokku domains plugin so your app can use domains instead of subdomains or ports.

Then add your domain to your your app using:

ssh dokku@<> domains:set <app_name>

MySQL / MariaDB

If your app uses MySQL, install the dokku MariaDB plugin (drop-in MySQL Replacement).

Then create a database for your app using:

ssh dokku@<> mariadb:create <app_name>

This will create a DATABASE_URL environment variable that will be available as a DSN string for your app to use to connect to the database via PDO or other ORM that you may want to use. You can access this in PHP via $_SERVER['DATABASE_URL'].

Other Plugins

If you use Redis, Memcached, or anything else, check the Dokku Plugins page and install whatever you need.

Step 8: Re-Deploy Your App

This time when you deploy your app via git push, it will use the custom buildpack you set in Step 4. You should be able to view your app live on your custom port, subdomain, or domain now, and all should be well.

Now sit back, relax, and enjoy your own mini-Heroku at a fraction of the cost!

Valitron: The Simple Validation Library That Doesn’t Suck

Valitron is a simple, minimal and elegant stand-alone PHP validation library with NO dependencies. Valitron uses simple, straightforward validation methods with a focus on readable and concise syntax.

Why Another Validation Library?

Valitron was created out of frustration with other validation libraries that have dependencies on large components from other frameworks unrelated to validation like Illuminate Validation (laravel 4) requiring  Symfony HttpFoundation, pulling in a ton of extra files that aren’t needed for basic validation. It also has purposefully simple syntax used to run all validations in one call instead of individually validating each value by instantiating new classes and validating values one at a time like Respect Validation requires you to do. Valitron also has a focus on being concise – validation rules are just a single line per rule, and can include multiple fields in an array. This is handy, because in most use cases, a single validation rule – like “required” will be applied to many fields, so it doesn’t make sense to start with the field first like Fuel Validation does.

In short, Valitron is everything you’ve been looking for in a validation library but haven’t been able to find until now: simple pragmatic syntax, lightweight code that makes sense, extensibility for custom callbacks and validations, good test coverage, and no dependencies.

Usage Example

Valitron is made to setup all your validation rules on the fields you need, and then run all the validations in one call. This is better than validating the fields one-by-one, because that approach causes a lot of “if” statements and branching logic that doesn’t make the resulting code any better than doing the validations by hand (which obviously sucks).

$v = new Valitron\Validator($_POST);
// Input array
$v->rule('required', ['name', 'email', 'date_start']);
$v->rule('email', 'email'); // Email uses filter_var
$v->rule('dateAfter', 'date_start', new \DateTime()); // After today
if($v->validate()) {
     echo "Yay! We're all good!";
} else {
     // Errors

More usage examples and documentation can be found on the Valitron GitHub Page. Valitron is on Packagist, and can be installed via Composer.

Introducing Bullet: The Functional PHP Micro-Framework

Bullet is a new PHP micro-framework with a unique functional approach to URL routing that allows for more flexibility and requires less verbosity than the more typical full route+callback approach found in other micro-frameworks.

The Problem with Independent Scope

The main problem with most micro-frameworks and even full-stack MVC frameworks that leads to code duplication is that the callback or method executed to perform the action and respond to the URL route lives fully within its own scope. This means that you are forced to repeat a lot of setup code across URL route handlers that load the same resource, authorize it, etc.

Some typical micro-framework code might look like this:

// View single post
$app->get('/posts/:id', function($id) {
     $post = Post::find($id);
     // ...

// Delete post
$app->delete('/posts/:id', function($id) {
     $post = Post::find($id);
     // ...

// Edit post
$app->get('/posts/:id/edit', function($id) {
     $post = Post::find($id);
     // ...

You may be able to move the ACL check to a middleware layer or “before” hook if the framework supports it, but there is always a certain amount of duplicate code you will either never be able to get rid of, or have to jump through hoops to get rid of (like adding more abstraction or re-checking the current URL, etc).

The Benefits of Shared Scope

Bullet uses a unique nested callback style that splits the URL by directory separator and only handles a single part of the URL at a time with it’s own callback. At first blush, this approach might seem like more work, but the key to how Bullet works is that nested closures – by definition – can use variables defined in the scope of their parent. This leads to some pretty powerful and profund capabilities that can only be done using the same nested closure style that Bullet uses.

Continue reading

Handling Exceptions in Gearman Tasks (Even Background Ones)

I recently had some issues with Gearman tasks throwing exceptions and killing the whole Gearman daemon. This made it nearly impossible to trace errors back to their origin, because the logged exception stack trace didn’t provide much useful information, because it just logged where it failed in Gearman – not the actual file and line of code that was doing the work. I dug into the code and started trying things like GearmanClient::setExceptionCallback and running the tasks, but since the tasks were being run with addTaskBackground instead of just addTask, the callbacks were never getting executed, and I still was not able to do anything to handle exceptions for the jobs that were being run (and they were still killing the Gearman daemon). Clearly, I was going to have to get a little more creative.

The only other place to add code that will catch exceptions for all jobs run is in the GearmanWorker::addFunction method. So I looked at the following one-liner for adding named job callbacks:

$worker->addFunction($name, $task);

And replaced it with a closure that uses a try/catch and then logs any exceptions to Exceptional so we can see the full stack trace and exact point of failure for any job – even background jobs:

$worker->addFunction($name, function() use($task) {
     try {
         $result = call_user_func_array($task, func_get_args());
     } catch(\Exception $e) {
         $result = GEARMAN_WORK_EXCEPTION;
         echo "Gearman: CAUGHT EXCEPTION: " . $e->getMessage();
         // Send exception to Exceptional so it can be logged with details
         Exceptional::handle_exception($e, FALSE);

     return $result;

And it works beautifully. Now all the jobs are run, the Gearman daemon is never killed by a PHP process, and all the exceptions are logged with full granular details that makes it easy to troubleshoot and fix any errors.

Nginx + PHP-FPM Blank Pages with PHAR Packages

Ran into this issue when setting up a new VPS for AutoRidge. This happens when using Nginx and PHP-FPM with PHP 5.3+ and the Suhosin patch when trying to run a PHP script using a PHAR package. From what I can gather, the Suhosin patch basically blocks PHP include/require functions from executing files ending with .phar, which results in a PHP segfault that leaves no trace of any error at all. This is what makes this error so frustratingly difficult to track down – there is no trace left in any logs about what is happening or that any PHP error even occurred at all.

The solution is to open your "suhosin.ini" file to ensure the Suhosin patch is allowing PHP to open and execute PHAR files.

Mine was at:


If your suhosin config file is not there and you don’t know where it is, run this:

locate suhosin.ini

Find the config key suhosin.executor.include.whitelist and add "phar" to it.

suhosin.executor.include.whitelist ="phar"

Then restart PHP-FPM and Nginx and you should be good to go!

/etc/init.d/php5-fpm restart /etc/init.d/nginx restart

How to add Photos to the iPhone Simulator

Building an app that needs to access the photo library but don’t have any photos in the iPhone simulator? No problem. Follow these simple steps to import photos into the iPhone Simulator:

  1. Open the iPhone Simulator
  2. Browse to the photo you want to put into the simulator (Finder or web browser)
  3. Click and drag the photo over the simulator window. A green "plus" icon should appear under your cursor with the simulator frame highlighted. Drop the photo.
  4. Mobile Safari should open on the simulator to the location of the image you just dragged and dropped over it
  5. Note that if the image you dropped is linked in a webpage, it will open the link instead of the image URL.
  6. Click the mouse down over the image and hold it until a popup window appears.
  7. Click "Save Image"

The photo will now reside in the "Saved Photos" album on the iPhone Simulator. Rince and repeat as many times as you need to get all your photos in the album.