What to Look for in PHP 5.4.0

PHP 5.4.0 will arrive soon. The PHP team is working to bring to some very nice presents to PHP developers. In the previous release of 5.3.0 they had added a few language changes. This version is no different. Some of the other changes include the ability to use DTrace for watching PHP apps in BSD variants (there is a loadable kernel module for Linux folks). This release features many speed and security improvements along with some phasing out of older language features (Y2K compliance is no longer optional). The mysql extensions for ext/mysql, mysqli, and pdo now use the MySql native driver (mysqlnd). This release also improves support for multibyte strings.

Built-in Development Server

In the past, newcomers to PHP needed to set up a server. There was no built in server like a few other languages/web frameworks already had. If developing on *nix, a server needed to be set up with the right modules and the the files to tested needed to be copied over to the document root. Now, you can just run PHP with some options to get a server:

$ php -S localhost:1337

It runs in the current directory, using index.php or index.html as the default file to serve. A different document root can be specified as either an absolute or relative path:

$ php -S localhost:1337 -t /path/to/docroot

The server will log requests directly to the console. Interestingly, this server will not serve your static files unless your script return false. Existing frameworks will need to be modified to add in functionality that is commonly in rewrite rules. This is really all that is needed:

// If we're using the built-in server, route resources
if (php_sapi_name() == 'cli-server') {
  /*
   * If the request is for one of these image types, return false.
   * It will serve up the requested file.
   */
  if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"]))
    return false;
}
// Process the rest of your script

One of the inconveniences of the server is lack of support for SSL. Granted, it is meant for development purposes only. However, some projects I’ve worked on required testing with SSL. Perhaps there will be demand for this once it’s out there.

An Overview of Traits

Traits are bits of code that other objects can use. Traits allow composing objects and they promote code reuse. The Self programming language, one of the precursors to the JavaScript language, introduced them. JavaScript, strangely, does not directly implement traits; instead it allows one to extend objects directly with other objects.

In PHP (and other languages), traits cannot be instantiated, only used to compose other objects. Traits do not imply inheritance, they just add methods to classes. They can be used with inheritance and interfaces. Traits could be used as standard implementations of interfaces, then one could easily compose classes that comply with certain interfaces.

Here is an example, demonstrating a simple use of traits:

<?php
/**
 * Define a trait called runner
 */
trait runner {
  // Does all the work
  public function run() {
    echo "Run, ".$this->name().", run!\n";
  }
  // Gets the name of the runner
  // Must be implemented by the class using the trait.
  abstract public function name();
}
/**
 * Define a class that uses the runner trait
 */
class runningPerson {
  // Use the runner trait
  use runner;
  // Used to store the person's name
  protected $name; // Constructor, assigns a name to the person
  public function __construct($name) {
    $this->name = $name;
  }
  // Retrieves the name of the person, required by runner trait
  public function name() {
    return $this->name;
  }
}
$gump = new runningPerson("Forrest");
$gump->run();

When a class implements a method that is also defined in a trait it uses, the method in the trait takes precedence and overrides the class method. If two traits implement the same method, the conflict needs to be resolved using the insteadof keyword, or given a new signature (only visibility and name can be changed) using the as keyword.

<?php
/**
 * Define traits with conflicting function names
 */
trait A {
  public function do_something(){
    echo "In A::do_something():\n";
    for($i = 0; $i < 10; $i++) {
      echo $i." ";
    }
    echo "\n";
  }
}
trait B {
  public function do_something(){
    echo "In B::do_something():\n";
    echo "Something else.\n";
  }
}
/**
 * Define a class using both traits
 * Prefers one over the other
 */
class ExampleA {
  use A, B {
    B::do_something insteadof A;
  }
}
/**
 * Define a class using both traits
 * Renames a function to use both
 */
class ExampleB {
  use A, B {
    A::do_something insteadof B;
    B::do_something as something_else;
  }
}

//Run examples
$testA = new ExampleA();
$testB = new ExampleB();
$testA->do_something();
$testB->do_something();
$testB->something_else();

More examples reside at the current PHP documentation for traits. If that documentation is lacking in substance, Wikipedia’s article on traits links plenty of background info.

Changes to Anonymous Functions

In PHP 5.3.x, working with anonymous functions needed a work around when stored in an array. The function needed to be stored in a temporary variable before it could be called. For instance:

$functions = array();
// assign an anonymous function to an array element
$functions['anonymous'] = function () {
  echo "Hello, the parser needs to make up a name for me...\n";
};
// to call it you had to do this:
$temp = $functions['anonymous'];
$temp();

Now, anonymous functions stored in an array can be called directly without first storing them in a temporary variable:

// assume $functions[] is still around.
$functions['anonymous']();

Closures in Classes

Closures defined inside of a class are automatically early bound to the $this variable. If a class method returns a closure, it retains access to the original class that defined it (along with all the public member properties and methods) no matter where it is passed. If assigned to a member property and called as a method, PHP issues a warning if it was called directly. If called as a local variable or by calling the Closure::__invoke() method (which it inherits), PHP issues no warning.

<?php
/**
 * Class that generates closures that reference a public method.
 */
class ClosureTest {
  private $value;

  public function setValue($value) {
    $this->value = $value;
  }

  public function getValue() {
    return $this->value;
  }

  public function getCallback() {
    return function() {
      return $this->getValue();
    };
  }
}

/**
 * Create a class that calls a closure.
 */
class ClosureCaller {
  private $callback;

  public function setCallback($callback) {
    $this->callback = $callback;
  }

  public function doSomething() {
    // Since this is a member variable, call Closure::__invoke().
    echo $this->callback->__invoke() . "\n";
  }
}

// Set up a class to generate closures that reference itself
$test = new ClosureTest();
$test->setValue(42);
$closure = $test->getCallback();
echo $closure() . "\n";

// Test calling a closure from another class
$testCaller = new ClosureCaller();
$testCaller->setCallback($test->getCallback());
$testCaller->doSomething();

Closures allow changing what object scope $this is bound to by calling the bindTo() method and passing in the new object to use as $this.

Currently, no consensus exists around letting closures bound to an object access the private and protected methods of that class. Additionally, PHP still needs to iron out the details around binding closures to static classes. One can find more details about closures, $this, and Closure::bindTo() at https://wiki.php.net/rfc/closures/object-extension

Outlook

There are a lot of established projects that may not immediately start taking advantage of these features, unless the community sees an obvious benefit to drastically changing their projects. When PHP 5.3.0 was released with namespace support and anonymous functions, new frameworks sprung up like Laravel (anonymous functions), FLOW3 (namespaces), Lithium (namespaces), and Symfony2 (namespaces). After PHP 5.4.0 is released, I’m sure new frameworks (or new versions, like Symfony2 vs. Symfony) will spring up around using traits to compose functionality and using the new $this functionality in closures defined in classes. The built in server definitely has some potential for making it easier for developers to debug their apps. It’s just a matter of time before frameworks start taking advantage of it.

Reference

PHP 5.4.0 Release Candidate 2 News

Advertisements

The State of Functional Programming in PHP 5.3.x

A few weeks ago, I started looking into the possibility of functional programming in PHP. I stumbled across the capability of defining anonymous functions — starting with PHP 5.3.0. These can be used to define closures with bound variables and also for partial application or currying. Higher order functions can also be defined.

All anonymous functions are implemented through the internal Closure class — which is strange since anonymous functions can be used to implement closures, but anonymous functions are not closures. It takes advantage of the __invoke() magic in PHP 5.3.x. This means that alternate implementations or libraries taking further advantage of anonymous functions could be created rather easily.

Anonymous Functions

It is very easy to define an anonymous function:


$variable = function ($arg) {
  return $arg+1;
};

This is very close to what JavaScript programmers typically call a closure, for reasons we’ll see shortly.

Note: In PHP 5.4.x (currently in alpha — development preview), an anonymous function defined inside of a class can use the $this variable to access class properties and methods.

Closures and Bound Variables

A closure is an anonymous function that encloses part of the external scope surrounding it. Here’s an example:


// Assign value to variable to be bound
$variable = 3;
// Create a closure using a variable outside of the scope of the anonymous function.
$closure = function ($arg) use($variable) {
  return $arg + $variable;
};

One must explicitly bind variables in the outside scope by using the keyword use. Binding variables in PHP is, by default, through early binding. This means that the values seen by the anonymous function are the values that were bound at the time the function was defined. One can implement late binding by passing in the variables to be bound by reference in the use parameters. For example:


// Define the greeting
$greeting = "Hello!\n";
// Define a function and bind a variable by reference (late binding)
$f = function() use(&$greeting) {
  echo $greeting;
};
// Run the closure
$f();
// Change the greeting
$greeting = "Hi!\n";
// Run the closure
$f();

This would output:


Hello!
Hi!

JavaScript uses late binding, where the value seen is whatever the bound variable’s value is at the time of the anonymous function’s execution. Variable scope overlaps one level of nesting — closures can access variables in the scope directly containing it. In PHP, I have nonesuch luck. This is why anonymous functions are commonly called closures in JavaScript, it is so common to use its implicit binding that most programmers don’t notice that they might not even be creating a real closure. (Since the variables in the containing scope are always available to the anonymous function (unless there are optimizations in the interpreter or compiler), it might technically still be a closure.)

Partial Application of Functions

If there is a general function that accepts many variables and one wants to create a function that fixes most of the variables, one can partially apply a function. This takes a function with a certain number of parameters and returns a function that accepts fewer parameters. For instance, I can take a saddle function (a 3-d function that looks like a saddle) and turn it into a 2-d parabola (which is actually the curve at y = 5):


$general_function = function($x, $y) {
  return $x*$x - $y*$y;
};
$partial_function = function($x) use($general_function) {
  return $general_function($x, 5);
};

Higher Order Functions

Higher order functions are functions that accept functions as their parameters. A common higher order function is the compose function. It accepts two functions and returns a function. All of the inputted functions must accept the same number of parameters and resulting function will accept the same number of parameters.


function compose(&$f, &$g) {
  // Return the composed function
  return function() use($f,$g) {
    // Get the arguments passed into the new function
    $x = func_get_args();
    // Call the function to be composed with the arguments
    // and pass the result into the first function.
    return $f(call_user_func_array($g, $x));
  };
}

Other common functions are map, filter, & fold (reduce in some cases).

The function map takes an array and a function, applies the function to each element in the array, returning the resulting array:


// Convenience wrapper for mapping
function map(&$data, &$f) {
  return array_map($f, $data);
}

The filter function takes an array and a function (boolean). It applies the function to each element in the array and appends it to the array if the function returns true.


// Convenience wrapper for filtering arrays
function filter(&$data, &$f) {
  return array_filter($data, $f);
}

The fold function aids in taking an array and turning it into a scalar (single) value:


// Convenience wrapper for reducing arrays
function fold(&$data, &$f) {
  return array_reduce($data, $f);
}

// sum over an array using the fold function
$sum = function ($values) {
  return fold($values, function($u, $v) {
    return $u += $v;
  });
};

Functions as Objects

Unfortunately, the class which is implemented internally for anonymous functions does not support instantiation. This has the side effect of not allowing the Closure class to be extended. This is not a huge deal, since the __invoke() magic could be used to create a class that can be used the same way as the internal class. For instance:


class Lambda {
private $anonymous;
  public function __construct($f) {
    $this->anonymous = $f;
  }
  public function __invoke() {
    $x = func_get_args();
    return call_user_func_array($this->anonymous, $x);
  }
}

$a = new Lambda(function($x) {
  return $x*$x;
});

$y = $a(5);
echo "$y\n";

If one implemented the ArrayAccess interface, one could create objects that as extensible as JavaScript objects.

Example Code

There are more examples for one to peruse over at my github account. Here are the links to the gists:

  1. Composing Functions in PHP
  2. Sketch of Making a Functional Style Controller (Please, don’t emulate this! This is terrible, I have a better way of doing it in the works.)
  3. Functional Programming in PHP