Skip to content

Instantly share code, notes, and snippets.

@nakamuray
Created August 26, 2011 07:58
Show Gist options
  • Save nakamuray/1172941 to your computer and use it in GitHub Desktop.
Save nakamuray/1172941 to your computer and use it in GitHub Desktop.
PHP object system written in PHP
<?php
function mro($class) {
$classes = class_parents($class);
array_unshift($classes, $class);
return $classes;
}
function get_parent($class) {
$parents = class_parents($class);
return array_shift($parents);
}
class __dict__ {
}
class Object {
//static private $__dict__;
public $__obj_dict__;
public $__class__;
static function __new__($class) {
$class->__init__ = function($self) { };
}
function __set($name, $value) {
return $this->__obj_dict__->$name = $value;
}
function __get($name) {
if (isset($this->__obj_dict__->$name)) {
return $this->__obj_dict__->$name;
} else {
foreach (mro($this->__class__) as $class) {
if (isset($class::__dict__()->$name)) {
return $class::__dict__()->$name;
}
}
}
//throw new RuntimeException('no such attribute');
return Null;
}
function __isset($name) {
if (isset($this->__obj_dict__->$name)) {
return True;
} else {
foreach (mro($this->__class__) as $class) {
if (isset($class::__dict__()->$name)) {
return True;
}
}
}
return False;
}
function __unset($name) {
unset($this->__obj_dict__->$name);
}
function __call($name, $arguments) {
array_unshift($arguments, $this);
return call_user_func_array($this->$name, $arguments);
}
function __construct() {
$this->__class__ = get_class($this);
foreach (array_reverse(mro($this->__class__)) as $class) {
// initialize class' __dict__
$class::__dict__($class);
}
$this->__obj_dict__ = new __dict__();
$arguments = func_get_args();
$this->__call('__init__', $arguments);
}
function super() {
$super_obj = clone $this;
$super_obj->__class__ = get_parent($this->__class__);
return $super_obj;
}
static function __dict__($class=Null) {
// use late static bindings to set $__dict__ per each subclasses
static $__dict__;
if ($class !== Null) {
// initialize $__dict__ if $class argument is passed
$__dict__ = new __dict__();
$class::__new__($__dict__);
}
return $__dict__;
}
}
if (!debug_backtrace()) {
class Hoge extends Object {
static function __new__($class) {
$class->__init__ = function($self, $name="world") {
$self->name = $name;
};
$class->method = function($self) {
print "hello {$self->name}\n";
};
}
}
class Fuga extends Hoge {
static function __new__($class) {
$class->method = function($self) {
print "hi, {$self->name}\n";
$self->super()->method();
};
}
}
class Piyo extends Fuga {
static function __new__($class) {
$class->__init__ = function($self, $name, $message) {
$self->message = $message;
$self->super()->__init__($name);
};
$class->method = function($self) {
print "{$self->message} {$self->name}\n";
$self->super()->method();
};
}
}
print "---------- Hoge ---------\n";
$h = new Hoge('hoge');
$h->method();
$h->method = function($self) { print "overridden\n"; };
$h->method();
$h2 = new Hoge('hoge2');
$h2->method();
print "---------- Fuga ---------\n";
$f = new Fuga();
$f->method();
print "---------- Piyo ---------\n";
$p = new Piyo('piyo', 'LOL');
$p->method();
$p->method();
class C1 extends Object {
static function __new__($class) {
$class->__init__ = function($self) {
$self->i = 0;
};
$class->incr = function($self) {
$self->i++;
};
}
}
print "---------- C1 ---------\n";
$c1 = new C1();
var_dump($c1->i);
$c1->incr();
var_dump($c1->i);
$c1_2 = new C1();
var_dump($c1_2->i);
class C2 extends C1 {
static function __new__($class) {
$class->incr = function($self) {
$self->super()->incr();
$self->i++;
};
}
}
print "---------- C2 ---------\n";
$c2 = new C2();
var_dump($c2->i);
$c2->incr();
var_dump($c2->i);
C2::__dict__()->incr = function($self) {
$self->i += 100;
};
$c2->incr();
var_dump($c2->i);
print "---------- C3 ---------\n";
class C3 extends C1 {
static function __new__($class) {
$class->__init__ = function($self) {
$self->i = 1000;
};
}
}
$c3 = new C3();
var_dump($c3->i);
$c3->incr();
var_dump($c3->i);
var_dump($c3 instanceof C3);
var_dump($c3 instanceof C2);
var_dump($c3 instanceof C1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment