You are currently browsing the archives for the php tag.

Prototype based PHP

Another proof of concept, using PHP this time :

<?php
class Proto {
  private $elems;
  private $proto;

  function __construct($proto = null) {
    $this->elems = array ();
    $this->proto = $proto;
  }

  function __set($name, $value) {
    $this->elems[$name] = $value;
  }

  function __get($name) {
    if ($this->elems[$name])
      return $this->elems[$name];
    else
      if ($this->proto)
        return $this->proto->$name;
      else
        return null;
  }

  function __call($name, $args) {
    if ($this->elems[$name] && is_callable($this->elems[$name]))
    {
      array_unshift($args, $this);
      return call_user_func_array($this->elems[$name], $args);
    }
    else
      return null;
  }

}
?>

The idead is completely different from the OCaml implementation. This time we use the magical methods to do whatever we want. Here is yesterday's example :

<?php
function write ($s) { echo $s; }
function method ($args,$body) { return create_function('$self,'.$args, $body); }

header('Content-Type:text/plain');

$p = new Proto;
$p->foo = 'p.foo';
$p->baz = 'p.baz';

$o = new Proto($p);
$o->foo = 'o.foo';
$o->bar = method('$f', '$f($self->baz);');

echo $p->foo, "\n";
echo $p->baz, "\n";
echo $o->foo, "\n";
$o->bar('write');
?>

There are several differences here too. First, echo is a statement, not a function, so it can't be passed to a function. This is why I use this workaround with the write function. Next, because of PHP's scoping, there is no direct access to the global variable $foo without calling global $foo;), I decided to $self as the first argument of all methodes and to bind it to the current element (this is actually how JavaScript works);

There are not much differences though…