Tag Archives: debugging

Mac popup notification for a PHP error

Receive a notification when PHP errors are logged on Mac

I have PHP configured to log all of its errors to a single log file. I always have Terminal open and tail watching this file. However, sometimes I don’t realize that new errors have been logged right away, which is annoying. To overcome this, I thought it would be nice if I could get a popup notification each time there was an error, just like many Mac apps do. I found this thread on SO, which helped me solve my problem.

If you have Homebrew installed, all you need to do is run:

$ brew install terminal-notifier
$ brew install fswatch

Then add this function to your .bash_profile:

notify-php-logs() {
	fswatch -0 ~/zebug.log | xargs -0 -n 1 \
		terminal-notifier -title "PHP Error" \
			-message "New errors in zebug.log" \
			-group "php-errors" \
			-activate "com.apple.Terminal"
}

Then run:

$ notify-php-logs >/dev/null 2>&1 &
$ tail -f ~/zebug.log

You’ll want to replace ~/zebug.log with the path of the log file that you want to listen to, of course.

Now whenever there is a PHP error, you will get a notification, and when you click on it the Terminal app will be brought to the front so you can see the error.

One time the unit tests failed me

Since my initiation into the world of unit testing about a year or so ago, I’ve been a huge fan of unit testing. I write unit tests for almost everything now, rather than doing repeated manual testing, which is sometimes more tedious (and certainly gets boring after a while).

But just now, the unit tests failed me. I’ll explain the case in a moment, but let me just say that, as great as unit tests are, they aren’t the only kind of testing you need. Doing manual beta testing is always needed for good measure.

So here’s what happened. I had written a custom module for my WordPoints plugin, with unit tests, of course. And the unit tests were passing fine.

That was last week. But before I tried it out on a live site, I wanted to test it manually on one of my local setups. And guess what. It didn’t work.

I eventually figured out that the issue was a bug in WordPoints, that was caused by WordPress having a 64 character limit for option names. I knew about this limit, but it hadn’t bitten me yet. I’d actually forgotten whether I’d handled the limit properly or not. But that is by the by.

What struck me after I figured out what was going on was this: “What about the unit tests I wrote, they passed fine!”

Yep, they did. And here’s why. For the unit tests, WordPress’s testcase sets up a database transaction before each test. Of course it doesn’t actually commit the data to the database, instead it rolls back the transaction after the test is done. This way, the database stays clean between tests, so they don’t leak into each other.

And this is why my tests didn’t fail. The data wasn’t actually getting committed to the database, so saving the option value wasn’t failing like it normally would. I assume that the database checks that the table and column names are all good, but doesn’t realize that you’re trying to write 65 characters to a VARCHAR(64) field until the data gets committed (which in this case it doesn’t).

In the end, I really think the issue here is that WordPress should fail, or tell us that we’re _doing_it_wrong(), when we try to use option names that are too long. But until then, we need to be careful, when using dynamic option names, that we check they aren’t too long. Especially since unit tests won’t be enough to catch the issue.

Debugging PHP: Inspecting Variables

When debugging in PHP, we often want to know exactly what a variable is. We often know what it should be, but when things don’t work as expected, we need to know whether that’s really what it is. There are several ways to inspect variables in PHP. Among them are the following functions, listed with their downsides:

  • var_dump() – This one does great with all sorts of data types, but only outputs the result; not very useful in some situations, especially when you’re (yikes!) debugging live.
  • print_r() – This one is OK for some data types, but gives no output when passed false. On the upside, it can return the string instead of outputting it directly.
  • var_export() – This produces a parsable string, which can be useful at times, but can also be difficult to comprehend.

Of these, var_dump() is often the best for debugging, because it tells you what data type the variable is. The problem is that it only outputs the result directly, which can be annoying as I pointed out above. I prefer to use the error log when I’m debugging. So that’s why I use the function below. It works exactly like var_dump() the only difference is that it logs the result to the error log instead of outputting it.

/**
 * Dump a variable to the error log.
 *
 * You can pass as many variables as you want!
 */
function var_log() {

	ob_start();
	call_user_func_array( 'var_dump', func_get_args() );
	error_log( ob_get_clean() );
}

Think carefully before adding this to your development environment. You may find it hard to live without!