Created
August 26, 2011 07:58
-
-
Save nakamuray/1172941 to your computer and use it in GitHub Desktop.
PHP object system written in PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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