A Look at PHP's Continuing Evolution

Guest post by Larry GarfieldLarry Garfield is a Senior Architect at Palantir.net, a web consultancy based in Chicago. When not developing sites for clients, he can also be found leading the Drupal 8 Web Services Initiative, evangelizing good coding practices, working to bring the PHP world closer together through the PHP Framework Interoperability Group, or providing training either for clients or the Drupal community. Occasionally he remembers to sleep.

PHP is not a young language. As of 2013, it's 18 years old; that's old enough to vote. Many upstart languages have appeared over the years to try and unseat PHP as the "lingua franca" of web applications but it still commands over 80% of the web market. One reason for PHP's popularity is no doubt the ease with which new developers can get started with it, but just as important is the fact that PHP has been evolving for all those 18 years.

Many PHP detractors had cited the language's sometimes inconsistent APIs or its procedural nature as a reason that PHP was just a "toy language." That charge is true... or rather, it was during the 1990s. What is true now is that PHP is an eclectic language that isn't bound to a single world-view or architecture – and this is one of its strengths. Procedural, Object-oriented, and Functional programming styles all have their pros and cons. PHP lets you pick and choose what to use rather than forcing everything and everyone into a single mindset.

Recent versions of PHP have expanded its capabilities, too, to keep up with evolving markets and technical requirements. Let's have a look at three of the more recent additions to PHP's arsenal that help it remain the world's leading server-side language.

Anonymous functions and closures

PHP 5.3 introduced anonymous functions to PHP for the first time. The syntax is quite simple, too:

$c = 5;
$max_cap = function ($a, $b) use ($c) {
  $max = max($a, $b);
  return min($max, $c);
$max_cap(3, 6);

This trivial function lets us create a routine that returns the maximum of 2 values, but with an overall limit. We can now call it from anywhere we pass $max_cap to. While this example may not be very useful per se, specifying one-off logic routines without a dedicated function can be extremely useful. Consider array_map(), which applies a function to every element of an array:

$factor = 3
$triple = array_map(function($elm) use ($factor) {
  return $elm * $factor;
}, $array);

$triple now contains all the elements of $array, multiplied by 3. There are far far more powerful opportunities with anonymous functions that can and have justified their own articles, so we'll leave that for now and just mention object binding.

As of PHP 5.4, anonymous functions can also be "bound" to an object. That is, $this within a closure can refer to an object we specify, like so:

class  Foo {
  private $count = 0;
$func = function() {
  return ++$this->count;
$foo = new Foo();
// second param specifies scope so it can access private vars.
$bound = $func->bindTo($foo, $foo);
print $bound(); // prints 1
print $bound(); // prints 2

For more on anonymous functions, see the PHP manual entries on anonymous functions and class closure.


PHP 5.4 also added a new feature for the OO crowd: Traits. Traits are, essentially, "compiler-assisted copy and paste" – or, sane multiple inheritance. They let you define methods that can be added to a class at code time without inheritance.

trait World {
  protected function scope() {
    return 'World';

class Hello {
  use World;
  public function hello() {
    return "Hello " . $this->scope();

To be sure, traits are not and should not be used as an alternative for object composition. Their main use is to minimize boilerplate code needed to fulfill an interface. Proper use of traits can greatly reduce boilerplate code while still allowing for clean separation and interface-centric development.

For more on traits, see the PHP manual entry on traits.


PHP 5.5 added a feature called generators. Generators are in some sense a greatly abbreviated syntax for iterators, but being so simple makes them considerably more powerful. Essentially, a generator is just a function that returns-and-pauses rather than returns-and-ends, and what is returned is not a value but an iterator. The canonical (if trivial) example is iterating an "array" with 10 million items, which normally would cause memory issues:

function xrange($start, $limit, $step = 1) {
  for ($i = $start; $i <= $limit; $i += $step) {
    yield $i;
foreach (xrange(1, 10000000, 5) as $i) {
  print $i . PHP_EOL;

PHP notices the yield keyword, so when xrange() is called, an iterator object is returned. Every time foreach() asks that object for the next value, xrange() runs until it hits a yield and returns that value; the next time it's called, it continues from right after that yield statement until it hits another yield or exits. The above code will print every 5th integer from 1 to 10 million, and use no more than a kilobyte of memory in the process.

You can also pass data into a generator via yield. For a less trivial example, let's copy data from one file to another, stripping out all comment lines along the way.

function no_comments($filename) {
  $handle = fopen($filename, 'r');
  while (($buffer = fgets($handle, 4096)) !== false) {
    if (strpos($buffer, '//') !== 0) {
      yield $buffer;

function stripped_file($file) {
  $f = fopen($file, 'a');
  while (true) {
    $line = yield;
    if (is_null($line)) {
    fwrite($f, $line);
$out = stripped_file('output.php');

foreach (no_comments('input.php') as $line) {

A tiny bit of setup and the resulting code at the end couldn't possibly be easier! And the memory usage is trivial.

You can read all about this, too, in the PHP manual entry on generators!


PHP has lasted as long as it has, and gained the marketshare it has because it is flexible. That flexibility is increasing with every version. We've only barely scratched the surface of modern PHP here. Since PHP 5.2, every release of the language has offered new features and functionality to give developers more power and more options than ever before.

That 80% marketshare is not going anywhere anytime soon.