LAMPlights Personal anecdotes from my experiences using the LAMP stack

13Mar/1010

PHP goes functional in version 5.3

It has been said that all languages, over time, implement a dialect of lisp.  PHP appears to be no exception. 

In PHP 5.3 lambda (or anonymous) functions and closures were added to the language.  These give PHP somewhat of a functional feel and can be very useful tools for solving problems.  One great example is the Lithium framework use of closures to implement filters.  Filters are an implementation of aspect oriented programming (AOP).  Other frameworks, like Zend Framework, are looking at these new functional tools to streamline complex and/or heavy components. I strongly believe that these new functional features will be the new "hotness" for PHP in the coming year. Expect quite a few conference sessions and tutorials devoted this very topic.

All this talk of functional language features is great, but Lithium is still in development, Zend Framework 2.0 is a ways away, you have an upcoming project deadline and you want to know how this stuff can help you now.  Easy: go read or watch JavaScript examples.  Seriously.  Watching Douglas Crockford's videos on YUI theatre or reading through ExtJS source code can give you really good insight into the power of functional language features.  The syntax may be different, but the core ideas are the same.

The new functional feel of PHP seems to have started a trend towards a unified constructor.  This has been a common practice in the JavaScript community for some time.  The great thing is that the PHP array is very similar to the JavaScript object.  In fact, the JSON extension to PHP makes them completely interchangeable.  Here is a quick example of one unified constructor implementation in PHP:

<?php
 
$p = array(
    'a' => 'hi',
    'adder' => function($n) { return $n + 1; },
    'c' => 3,
    'd' => new stdClass
);
 
class base {
    function __construct(array $params)
    {
        foreach ($params as $key => $value) {
            $this->$key = $value;
        }
    }
}
 
class foo extends base { }
 
$foo = new foo($p);

I have a bunch of ideas (some great, some maybe not so great) that I plan on implementing using lambda functions and closures. I will be adding new components to my Crimson library and discussing them here.

Reblog this post [with Zemanta]
  • http://www.milesj.me Miles Johnson

    One awesome thing I use closures for is lazy-loading of dependencies. I built this prototype structure where you can attach dependencies to an object using closures, and they won’t be instantiated till you call them. Well help a lot with overhead and unneeded objects.

    I’ll show you it soon.

  • Herman Radtke

    That sounds awesome. Can’t wait to see that.

  • Pingback: Using Absolute URL’s In The View | LAMPlights

  • http://www.johnkleijn.nl John Kleijn

    I don’t want to be negative, but that doesn’t do you much good. Yes, the simple example you posted will work, but try using $this. There’s no way to change the cope of the closure to that of the object you are making it a member of, like one can do in JavaScript.

    Yes, you could pass the object using the “use” keyword after it has been instantiated and attach the closure afterwards. But then why use a closure at all, an aggregate object would be a more flexible yet verbose solution. Another argument could be that it is easier to attach a closure than it is to create a method that delegates to an part object of the aggregate. Easier, yes. But you also add a method that is not defined in any interface whatsoever, as a result the clients of that method are brittle.

    I found closures in PHP 5.3 mostly useless. Like a kid with a new toy, I tried to find valid uses for them, believe me. But almost every time I found myself writing a class of adding a method somewhere to replace the closures I had written in my enthusiasm. The nett result is that I use em for simple callbacks to pass to functions, that’s all. They’re limited, and not type safe.

    Also this “lazy-loading of dependencies” sounds like Virtual Proxy (PoEAA), which is a well established design pattern that does the same, but type safe (it extends the subject class, but has an instance as a composite and only constructs the subject when the interface is used). “An object that doesn’t contain the contents, but knows how to get it”. Something like that, it’s from memory. If you want Fowler’s exact words look in PoEAA.

    I digress.. What I am saying is closures are NOT the next hot thing, they don’t really add anything. You can accomplish exactly the same and more using the features in that have been present since PHP 5.1. Don’t let you enthusiasm get the better of you.

  • Herman Radtke

    Hi John,

    Thanks for your comments. I don’t think closures replace good OOP code, but I do think they can be useful. I think I demonstrate a real nice use case for closures in my post here: http://www.hermanradtke.com/blog/using-absolute-urls-in-the-view/. Also, the Lithium framework is doing some really cool stuff with closures, such as implementing AOP. That all being said, the majority of my code will still be vanilla PHP 5 for the foreseeable future.

  • http://www.johnkleijn.nl John Kleijn

    I agree, that’s the point I’ve been making: they do not replace proper OO code. In the end, whether you immediately recognize it or not, you are using an adhoc solution. I took a look at your other post and Eli White’s post.

    And I must admit, when I read Eli’s post my first instinct was to see the improvement compared to using conditionals. But when you look at it sec, you see that there’s nothing special about it, you have been doing it for years.

    This:

    if ($jsfunc) {
    $url = function ($p) use ($jsfunc) { return “javascript:{$jsfunc}({$p})”; };
    } elseif ($baseurl) {
    $url = function ($p) use ($baseurl) { return “{$baseurl}/page:{$p}”; };
    }

    Can just as easily be written as this:

    class ElisUrlViewHelper {

    private $_baseUrl;
    private $_jsFunc;

    public function __construct($baseurl, $jsfunc){
    $this->_baseUrl = $baseurl;
    $this->_jsFunc = $jsfunc;
    }

    public function render($p){
    if ($jsfunc) {
    return “javascript:{$jsfunc}({$p})”;
    } elseif ($baseurl) {
    return “{$baseurl}/page:{$p}”;
    }
    }
    }

    $urlHelper = new ElisUrlViewHelper($baseurl, $jsfunc);

    //..
    echo $urlHelper->render($p);

    More boilerplate, yes. But also a well defined stateful interface, there is simply no substitution for that. My point is that that while closures can reduce conditionals, with a tiny bit of effort you can create a safe and extensible replacement. The only application where that doesn’t add any value is when you pass a callback directly as an argument to a function that isn’t type safe anyway.

    I haven’t looked at Lithium’s use of closures yet, but I am confident there is a “proper” OO alternative for that as well.

  • http://www.johnkleijn.nl John Kleijn

    Actually I took PoEAA from the shelve to look up virtual proxy in hopes of some comments about dependency injection, and it turns out its not in there. It’s in GoF, p208. Aaanyway..

  • http://www.johnkleijn.nl John Kleijn

    Wrote up an explanation of Virtual Proxy here: http://www.johnkleijn.nl/2010/Virtual-Proxies-revisited

  • http://www.milesj.me Miles Johnson

    @John Kleijn – I think you simply write OOP code just to write pure OOP code. Not everything has to be written that way. I would so prefer using Hermans URL class than the one you provided.

  • http://www.johnkleijn.nl John Kleijn

    If there’s an argument in that comment it eludes me. You might as well label me an OO purist, I hear that works too. Nothing *has* to be written in any way, as long as it is valid syntax. That doesn’t mean some ways are not preferable to others.

    That view helper was an alternative for Eli White’s closure, not Crimson_Url, which arguably is a better solution because it allows reuse of the procedure (or rather it allows recreating the procedure). But fine, lets consider the same problem and solution without closures:

    class Crimson_Url_Absolute
    {
    private $_host;
    private $_path;

    public function __construct($host)
    {
    $this->_host = $host;
    }

    public function setPath($path)
    {
    $this->_path = $path;

    return $this;
    }

    public function __toString()
    {
    return “{$this->_host}{$this->_path}”;
    }
    }

    $www = new Crimson_Url_Absolute(‘http://www.example.com‘);
    $ssl = new Crimson_Url_Absolute(‘https://www.example.com‘);

    echo $www->setPath(‘/foo.jpg’) . PHP_EOL;
    echo $ssl->setPath(‘/secure.php’) . PHP_EOL;

    Now be absolutely honest: is that really more work by any order of significance? I don’t think so. But at the same time you get all the benefits and possibilities that come with a stateful interface, such as polymorphism. If you don’t see the value of that this argument is moot and I’ll gladly leave you alone.

  • http://www.johnkleijn.nl John Kleijn

    Actually, using __invoke the syntax in the template can be exactly the same:

    class Crimson_Url_Absolute
    {
    private $_host;
    private $_path;

    public function __construct($host)
    {
    $this->_host = $host;
    }

    public function setPath($path)
    {
    $this->_path = $path;

    return $this;
    }

    public function __invoke($path)
    {
    return $this->setPath($path);
    }

    public function __toString()
    {
    return “{$this->_host}{$this->_path}”;
    }
    }

    $www = new Crimson_Url_Absolute(‘http://www.example.com‘);
    $ssl = new Crimson_Url_Absolute(‘https://www.example.com‘);

    echo $www(‘/foo.jpg’) . PHP_EOL;
    echo $ssl(‘/secure.php’) . PHP_EOL;