Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?PHP
- CLASS A EXTENDS FU
- {
- protected static $__autoConfig =
- [
- 'baz' => 'merge', 'bob', 'foo'
- ];
- protected static $__defaultConfig =
- [
- 'baz' => 1,
- 'bob' => 10,
- 'foo' => 100,
- ];
- }
- CLASS B EXTENDS A
- {
- protected static $__autoConfig =
- [
- 'baz', 'bob' => 'merge', 'bar'
- ];
- protected static $__defaultConfig =
- [
- 'baz' => 5,
- 'bob' => 50,
- 'bar' => 5000,
- ];
- }
- /*
- A::baz => merge
- A::bob
- A::foo
- B : A
- B::baz
- B::bob => merge
- B::bar
- expected:
- B::baz
- B::bob => merge
- B::foo
- B::bar
- */
- $fu = new B;
- var_dump($fu);
- return;
- /*
- object(root\B)#6 (2) {
- ["__initConfig":protected]=>
- array(5) {
- ["__run"]=>
- bool(true)
- ["baz"]=>
- int(5)
- ["bob"]=>
- int(50)
- ["foo"]=>
- int(100)
- ["bar"]=>
- int(5000)
- }
- ["debug"]=>
- &array(2) {
- ["__autoConfig"]=>
- array(4) {
- [0]=>
- string(3) "baz"
- ["bob"]=>
- string(5) "merge"
- [1]=>
- string(3) "bar"
- [2]=>
- string(3) "foo"
- }
- ["__defaultConfig"]=>
- array(4) {
- ["baz"]=>
- int(5)
- ["bob"]=>
- int(50)
- ["foo"]=>
- int(100)
- ["bar"]=>
- int(5000)
- }
- }
- }
- */
- class fu
- {
- /**
- * @late-state
- */
- protected static $__defaultConfig = [];
- /**
- * @late-state
- */
- protected static $__autoConfig = [];
- /**
- * @read-only
- */
- protected $__initConfig = [];
- /**
- * @cache
- */
- private static $__configCache = [];
- /**
- * @cache
- */
- private static $__parentClassCache = [];
- /**
- * @template
- */
- private static $__baseConfig =
- [
- '__run' => TRUE
- ];
- final public function __construct(array $__options = [])
- {
- $this->collect()->__initConfig = $this->extend
- (
- TRUE,
- self::$__baseConfig,
- self::$__configCache[get_called_class()]['__defaultConfig'],
- $__options
- );
- $this->debug =& self::$__configCache[get_called_class()];
- return TRUE === $this->__initConfig['__run']
- ? $this->__run()
- : $this;
- }
- protected function __run()
- {
- }
- public static function parents($__className = NULL)
- {
- $parentClasses = &self::$__parentClassCache;
- $class = NULL === $__className ? get_called_class() : $__className;
- if(isset($parentClasses[$class]))
- return $parentClasses[$class];
- $classes = [];
- do
- {
- $classes[] = $class;
- }
- while($class = get_parent_class($class));
- $parentClasses[$class] = $classes;
- return $classes;
- }
- /**
- *
- *
- * replace:
- * $c->extend(['myNewBar' => ['foo' => 'blop']]);
- * $c->extend(['myNewBar' => ['fob' => 'baz']]);
- *
- * ["myNewBar"]=>
- * array(1) {
- * ["fob"]=>
- * string(3) "baz"
- * }
- *
- *
- * extend:
- * $c->extend(['myNewBar' => ['foo' => 'blop']]);
- * $c->extend(true, ['myNewBar' => ['fob' => 'baz']]);
- *
- * ["myNewBar"]=>
- * array(2) {
- * ["foo"]=>
- * string(4) "blop"
- * ["fob"]=>
- * string(3) "baz"
- * }
- *
- * extend multi:
- * $c->extend(['myNewBar' => ['foo' => 'blop']]);
- * $c->extend(true, $c, ['myNewBar' => ['fob' => 'baz']], ['myNewBar' => ['bla' => 'baz']]);
- *
- * ["myNewBar"]=>
- * array(3) {
- * ["foo"]=>
- * string(4) "blop"
- * ["fob"]=>
- * string(3) "baz"
- * ["bla"]=>
- * string(3) "baz"
- * }
- *
- * @callable array $__data
- * @callable array $__target, array $__data
- * @callable bool $__recursive, array $__data
- * @callable bool $__recursive, array $__target, array $__data
- * @param mixed
- * @return array|this
- * @note $tar is not a referenced array
- */
- public function extend()
- {
- $args = func_get_args();
- $tar = $args[0];
- $i = 1;
- $length = count($args);
- $rec = false;
- if($tar === true || $tar === false)
- {
- $rec = $tar;
- $tar = isset($args[1]) ? $args[1] : [];
- $i = 2;
- }
- if(!is_array($tar) && !is_object($tar))
- $tar = [];
- if($length === $i)
- {
- $tar = $this;
- --$i;
- }
- for( ; $i < $length; $i++)
- {
- if(NULL === ($opt = $args[$i]))
- continue;
- foreach($opt as $key => $value)
- {
- switch(TRUE):
- case is_array($tar):
- $tar[$key] = (TRUE === $rec && is_array($value) && isset($tar[$key]) && is_array($tar[$key]))
- ? $this->extend($rec, $tar[$key], $value)
- : $value;
- break;
- case is_object($tar):
- $tar->$key = (TRUE === $rec && is_array($value) && isset($tar->$key) && is_array($tar->$key))
- ? $this->extend($rec, $tar->$key, $value)
- : $value;
- break;
- case is_string($tar):
- $tar::${$key} = (TRUE === $rec && is_array($value) && is_array($tar::${$key}))
- ? $this->extend($rec, $tar::${$key}, $value)
- : $value;
- break;
- endswitch;
- }
- }
- return $tar;
- }
- private function __collect()
- {
- $class = get_called_class();
- if(isset(self::$__configCache[$class]))
- return $this;
- self::$__configCache[$class] = [];
- // merge + cache __autoConfig, __defaultConfig from childClass up to baseClass
- // __autoConfig: array_unique(array_merge())
- // __defaultConfig: childClass extends recursively parentClass
- $cache = &self::$__configCache[$class];
- foreach($this->parents($class) as $lookup)
- {
- foreach(['__autoConfig', '__defaultConfig'] as $property)
- {
- if(!isset($lookup::${$property}))
- continue;
- $value = $lookup::${$property};
- if(!isset($cache[$property]))
- $cache[$property] = [];
- switch($property):
- case '__autoConfig':
- foreach($value as $key => $flag)
- {
- $search = is_string($key) ? $key : $flag;
- if(isset($cache[$property][$search]))
- continue;
- $cache[$property][$search] = is_string($key) ? $flag : '';
- }
- break;
- case '__defaultConfig':
- if(is_array($cache[$property]) && is_array($value))
- $cache[$property] = $this->extend(TRUE, $value, $cache[$property]);
- break;
- endswitch;
- }
- }
- return $this;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement