Tag Archives: PHP

Tilde expansion in PHP

If you have ever written a PHP command line script and tried to pass a file to it using the POSIX tilde (~) shortcut to reference your home directory, you may have been surprised to learn that the operating system does not automatically expand tildes in paths.

You’ll get an error like this:

Warning: fopen(~/file.csv): failed to open stream: No such file or directory

Fortunately, it is an easy matter to perform tilde expansion, once you know you need to.

function expand_tilde($path)
    if (function_exists('posix_getuid') && strpos($path, '~') !== false) {
        $info = posix_getpwuid(posix_getuid());
        $path = str_replace('~', $info['dir'], $path);

    return $path;

H/T to Ernest Friedman-Hill for cluing me into the solution.

Send mail() using PHP on Mac OS X

Thanks to Benjamin Rojas, Andy Stratton, and a tip from Jasper, I was able to successfully send email from my home-brewed MAMP environment. Here’s the summary.

  1. Add the following to your /etc/postfix/sasl_passwd file:
    smtp.gmail.com:587 username@gmail.com:password

    (Of course, you don’t have to use GMail or port 587, but you get the idea.)

  2. Configure postfix:
    sudo postmap /etc/postfix/sasl_passwd
  3. Backup and edit your postfix configuration:
    sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.orig
    sudo vim /etc/postfix/main.cf

    If you use TLS, then you will need to add the TLS settings but the other settings should already be there as a result of running the postmap command. You should have these options set in /etc/postfix/main.cf:

    mydomain_fallback = localhost
    mail_owner = _postfix
    setgid_group = _postdrop
  4. Start postfix:
    sudo postfix start

    If there are errors, you may need to edit your /etc/postfix/main.cf and restart postfix:

    sudo postfix reload
  5. Send a test message:
    date | mail -s test youremailaddress@yourdomain.com
  6. Make postfix start automatically on boot by opening your /System/Library/LaunchDaemons/org.postfix.master.plist file and adding:

    Add this at the bottom just before the closing </dict> tag.

  7. Edit your /etc/php.ini file and configure the sendmail_path option:
    sendmail_path = "sendmail -t -i"

You should now be able to send email using PHP’s mail() function. If you continue to have issues, watch the contents of your postfix mail log:

tail -f /var/log/mail.log

What Is Wrong With PHP’s Semaphore Extension

Lack of a true Semaphore

sem_release() releases the semaphore if it is currently acquired by the calling process, otherwise a warning is generated.

By far the worst, this limitation makes a whole class of problems much more difficult to solve, and in fact means that PHP’s Semaphore extension, despite the name, is really a mutex (a semaphore with ownership, i.e., only the acquirer may release). Furthermore, it is inconsistent with the behavior of equivalent functions in other languages such as C and Python.

Please see phm\Lock\Semaphore for a kludgy workaround using mutexes, shared memory, and a message queue. Continue reading

Roll your own MAMP development environment

Pre-packaged MAMP, LAMP, and WAMP stacks have been common on developer’s computers for years. Such packages are convenient because they provide a single-step install process, with all components in the server stack preconfigured to work together, and off you go.

Except when they don’t.

I’ve learned from experience that these packages have ways of making you pay for the convenience you enjoyed up front. If you have ever needed to:

  • Install a PHP extension that wasn’t already provided in your stack
  • Run a specific version of PHP or MySQL
  • Install PEAR packages
  • Install SSL certificates
  • Run command-line PHP scripts

…you may have encountered some ugly, time-wasting surprises along the way.

It pays to know your environment inside and out. Today, it is quite easy to roll your own Apache-MySQL-PHP stack on Windows, Linux, or even Mac OS X. Continue reading

Box drawing in PHP

Back in the “good old days” of MS-DOS, you could draw lines, boxes, filled areas (think progress bars), and more using the extended ASCII character set (AKA code page 437).

While writing a simple command-line utility in PHP I wanted to use the full block () and light shade () characters to create a simple progress bar that is a bit nicer than the typical =========....................

Like this:

█████████████████░░░░░░░░░░░░░░░░░░░░░░░ 42.5%

Instinctively, I turned to PHP’s chr() function and looked up the extended ASCII codes for the characters I needed. Boy, was I disappointed when my progress bar was nothing but a series of un-useful question marks. Surely PHP can render simple ASCII characters, I thought.

It might have gone differently if I had been using a PC, but I do 100% of my development these days on a Macbook Pro. It so happens that the bash shell in UNIX, Linux, and Mac OS X all use UTF-8 encoding by default, not CP437. (Of course, your terminal font will need to support UTF-8 characters for this to work.)

So, I just needed to find the UTF-8 codes for the characters I needed and use those instead of the old familiar CP437 ones. However, the results weren’t much better.

After an hour or more of Googling and experimentation, I finally realized that chr() doesn’t do UTF-8. I found various suggestions on how to produce the desired characters using custom functions and the like, but the best way turned out to just use a good ‘ol HTML entity and run it through html_entity_decode:

$block = html_entity_decode('&#x2588;', ENT_NOQUOTES, 'UTF-8'); // full block
$shade = html_entity_decode('&#x2591;', ENT_NOQUOTES, 'UTF-8'); // light shade

Now, a progress bar isn’t exactly a box, so let’s demonstrate:

$tl = html_entity_decode('&#x2554;', ENT_NOQUOTES, 'UTF-8'); // top left corner
$tr = html_entity_decode('&#x2557;', ENT_NOQUOTES, 'UTF-8'); // top right corner
$bl = html_entity_decode('&#x255a;', ENT_NOQUOTES, 'UTF-8'); // bottom left corner
$br = html_entity_decode('&#x255d;', ENT_NOQUOTES, 'UTF-8'); // bottom right corner
$v = html_entity_decode('&#x2551;', ENT_NOQUOTES, 'UTF-8');  // vertical wall
$h = html_entity_decode('&#x2550;', ENT_NOQUOTES, 'UTF-8');  // horizontal wall

echo $tl . str_repeat($h, 15)  . $tr . "\n" .
     $v  . ' Hello, World! '   . $v  . "\n" .
     $bl . str_repeat($h, 15)  . $br . "\n";


UTF-8, once you get used to it, actually provides many more possibilities than CP437 did back in the MS-DOS days. Enjoy!

Just-in-time $GLOBALS

Update—Turns out, this isn’t actually a bug. Rasmus Lerdorf has already explained this behavior in response to a bug report:

This is not a bug. It is a documented optimization feature. See http://php.net/manual/en/ini.core.php and look for the section on auto_globals_jit with the big pink warning which says, “Usage of SERVER and ENV variables is checked during compile time so using them through e.g. variable variables will not cause their initialization.”

I encountered an odd bug in PHP 5.3.10 while attempting to loop through all the major superglobals ($_SERVER, $_GET, $_POST, etc). Here is what I found, if you can shed any light on why this happens, or if you can confirm that it isn’t just me, I would greatly appreciate it!

Test Case

// These behave the same way:
// $var = '_SERVER'; var_dump($$var);
// var_dump(${$var});

Expected Behavior

$GLOBALS["_SERVER"]: array(27) {

Actual Behavior



What makes this so strange is that if you access $_SERVER (or ${'_SERVER'}) directly in the code anywhere—even if it doesn’t actually get executed—this bug does not manifest itself! In other words, this works just fine:

$var = $_SERVER;

Lone Star PHP takeaways

Thanks to the guys at Engine Yard, I won a free pass to the Lone Star PHP community conference in Dallas, TX this year. Due to the choice of subject matter and presenters, I think I enjoyed this conference even more than last year’s PHPCon in Nashville. Here are some of the highlights.

Day 1


Cal Evans inspired us all to go out and build awesome stuff, and that we owe a debt to the giants who came before us and gave, to give to those coming after.

  • “This stuff is hard. If it looks easy, it’s because I’m good at it.”
  • Get involved somewhere.
  • Be a builder, a speaker, a teacher.

Building Testable PHP Applications

Chris Hartjes delivered a really helpful talk on testing applications. One of the big obstacles of unit testing for me was mock objects. Chris did a good job explaining how they are used in the context of PHPUnit. Key takeaways for me:

  • Automate test execution.
  • Following the law of demeter will make your applications easier to test.
  • Code in a framework-agnostic and environment-agnostic way.
  • PHPUnit provides methods for setting up mock objects, so you don’t have to actually define those classes.
  • Test private/protected methods and properties by using a Reflection hack. Etsy’s PHPUnit extensions can automate this.
  • Don’t access the database in Unit tests, use mock objects instead. Filesystem access can be mocked using vfsStream.
  • Some applications resist testing, no matter what. If you cannot refactor, you can still automate tests with Behat.
  • If you don’t test, Chris will cut you!

See his slides at SpeakerDeck.com.

PHP Extensions for Dummies

Elizabeth Smith laid bare the innards of PHP in her intro to PHP extension development. Much of it was unintelligible to me since I don’t (yet) know C. However, now I know who to go to if I need help compiling an extension! If I can navigate the dependencies, I’d like to try compiling a non-thread-safe Windows build of php_wkhtmltox for a future blog post.

Pixel Punching with PHP

Bob Majdak‘s presentation compared the usage and performance of GD2 and IMagick across a number of common image manipulation tasks. IMagick is better in almost every way.

See his slides at SpeakerDeck.com.

Day 2

It Was Like That When I Got Here: Steps Toward Modernizing a Legacy Codebase

Paul Jones‘ keynote did not disappoint. With insight and humor, Paul dismantled the problems with legacy codebases and presented a logical methodology to improving your life when you are forced to inherit a big stinkin’ pile of spagetti code.

  • No matter how bad you want to, resist the urge to throw it out and rewrite.
  • You’ve nothing to lose. Either bear the pain of bad code, or bear the pain of refactoring bad code. May as well put the suffering to some use.
  • Move class files to a common base directory and autoload, removing require/include calls as you go.
  • Change class names as you go, if needed.
  • Wrap procedural functions in a class, so that it can be autoloaded.
  • Replace globals incrementally, moving them first to the constructor, then replacing them with dependency injection

SOLID – Not Just a State Of Matter, It’s Principles for OO Propriety

Chris Weldon laid out five principles to get the most out of object oriented development.

  • Single responsibility: each class should do one and only one thing.
  • Open/Closed principle: each class is open to extension, but closed for modification. Don’t break stuff.
  • Liskov Substitution principle: replace if…else constructs and prevent exceptions by using typed collections.
  • Interface segregation: each interface should be as focused as possible, so that it can be used by as many classes as need it. Similar to the Open/Closed principle, applied to interfaces.
  • Dependency Inversion: injection dependencies from the outside, don’t couple on the inside.

Fast, Not Furious: Performance Tuning that Works

Davey Shafik demonstrated how to use xhprof/xh-gui and Memcache to optimize your PHP application.

  • 1. Benchmark. 2. Profile. 3. Change.
  • Profiling affects performance, similar to quantum observation.
  • Benchmarking tests actual runtime, from start to end.
  • Namespacing Memcache keys can help overcome the 1MB size limit
  • Create new namespaces, don’t clear the cache. Garbage collection will clean up the old unused namespaces.
  • “Hardware is cheap, programmers are expensive” only holds when you take care of your hardware.
  • Don’t make assumptions, test everything sequentially.

Unshorten URLs with PHP and cURL

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 thirdparty service.

Improving slightly on this function, here’s how I did it in PHP:

function unshorten_url($url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, array(
        CURLOPT_FOLLOWLOCATION => TRUE,  // the magic sauce
        CURLOPT_SSL_VERIFYHOST => FALSE, // suppress certain SSL errors
    $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
    return $url;

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.