Oddly, other commands execute fine from PHP using shell_exec(). Even more strangely, the external program ran fine when executed from a PHP command-line script, just not from MAMP’s bundled version of Apache!

While working on a site that provides previews of URLs embedded in tweets using the awesome PhantomJS scriptable WebKit browser, and encountered difficulties when an URL shortener such as Bit.ly was used (as is almost always done when tweeting out a link to an interesting article or photo).

After a little experimenting, I discovered that cURL makes it super easy to un-shorten a URL that has been shortened, without depending on a third–partyservice.

That’s all you have to do. This works even if multiple URL shorteners are used in sequence on the same link, and in the event of an error, you’ll just get the same link back that you started with.

This seems to be a bit more robust than some of the other solutions floating around the ‘net, since it doesn’t try to hack the response headers or body (which could change without notice), and it will recurse as many times as it needs to up to the value of the CURLOPT_MAXREDIRS setting.

While on my day job over at Company 52, I encountered a textured background with a gradient overlay, using Photoshop’s overlay blending mode. I’m sure you’ve seen this effect before:

My first thought was to save the texture as a 4×4 PNG for tiling, and to save the gradient as a PNG with alpha transparency to overlay over the tiled pattern. This would certainly be lighter than saving a monolithic image, but this presented several problems:

The size of the gradient PNG was still too large, especially when the gradient can be done in CSS

The gradient overlay would be overlaid like Photoshop’s normal blending mode, not in the desired overlay mode, which would make the background look washed out.

Building MySQL web applications with a team of developers will inevitably present the challenge of database schema changes. Any good web developer understands the importance of keeping all code under version control, but how many follow the same principle for the database?

What follows are some best practices that I have learned over the past several years from the school of hard knocks. Continue reading →

Since this is a single gigantic regex, I suspect that it would run more slowly than the previous version, and is also more challenging to modify.

Instead of browser user-agent sniffing, you might want to consider using browser feature detection instead to tailor your application to the capabilities of the browser, rather than relying on the userAgent string (which can be customized in most browsers).

After three recent virus infections on Windows XP and Windows 7 (including at least one rootkit infection), I turned to Ubuntu Linux as a safer operating system. Two of the PCs were blessed with Atheros-based wireless network adapters, which are well-supported on Linux. The other laptop, a Dell Inspiron 2200, is blessed with one of those infamous Broadcom chipsets.

If you have ever touched a MySQL slave, you know that they can and do frequently halt. While sync problems can be caused by many things—network outages, schema changes, etc—one of the most common problems in a dual-master setup is primary key collision.

Primary Key Collision

…happens when records are added on two different servers to the same table and get the same AUTO_INCREMENT value. Fortunately, there is a trivially easy way to prevent this from happening.

auto-increment-increment=N

Adding this to your my.cnf or my.ini file will make AUTO_INCREMENT increment by N rather than by 1. N is the number of replicated servers that are masters.