Skip to content

Instantly share code, notes, and snippets.

@x7c1
Created September 11, 2011 17:11
Show Gist options
  • Save x7c1/1209834 to your computer and use it in GitHub Desktop.
Save x7c1/1209834 to your computer and use it in GitHub Desktop.
prototype-based oop in php
<?
namespace prototype;
class Klass{
public static function create($constructor){
return new KlassEntity($constructor);
}
}
class KlassEntity {
public $prototype;
private $constructor;
public function __construct($constructor){
$this->constructor = $constructor;
$this->prototype = new \StdClass;
}
public function create(){
return new Instance(
$this->prototype, $this->constructor, func_get_args());
}
public function bindTo($target){
return $this->constructor->bindTo($target);
}
public function prototype($kvs){
foreach($kvs as $k => $v){
$this->prototype->$k = $v;
}
}
}
class Instance {
private $prototype;
public function __construct($prototype, $constructor, $args){
$this->prototype = $prototype;
call_user_func_array($constructor->bindTo($this), $args);
}
public function __get($key){
return $this->prototype->$key;
}
public function __call($method, $args){
$callee = $this->$method->bindTo($this);
return call_user_func_array($callee, $args);
}
}
<?
include_once 'prototype.php';
use Prototype\Klass;
class TestPrototype extends PHPUnit_Framework_TestCase{
public function test_sample(){
$Person = Klass::create(function($first, $last){
$this->_first = $first;
$this->_last = $last;
});
$Person->prototype([
'getFullname' => function(){
return $this->_first . " " . $this->_last;
},
'getFirstname' => function(){
return $this->_first;
},
]);
$john = $Person->create('John', 'Smith');
$john->getLastname = function(){
return $this->_last;
};
$this->assertSame('Smith', $john->getLastname());
$this->assertSame('John Smith', $john->getFullname());
$inherit = function($parent){
$child = Klass::create(function() use($parent){
call_user_func_array(
$parent->bindTo($this), func_get_args());
});
$tmp = Klass::create(function(){});
$tmp->prototype = $parent->prototype;
$child->prototype = $tmp->create();
return $child;
};
$Person2 = $inherit($Person);
$john2 = $Person2->create('John2', 'Smith');
$this->assertSame('John2 Smith', $john2->getFullname());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment