Skip to content

Instantly share code, notes, and snippets.

@Jeff-Russ
Last active January 11, 2017 02:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jeff-Russ/bcf63ab0e60c88a22cb19c968dd60543 to your computer and use it in GitHub Desktop.
Save Jeff-Russ/bcf63ab0e60c88a22cb19c968dd60543 to your computer and use it in GitHub Desktop.
<?php
class Dynamic {
public static $static_methods = array();
// we can't have a $static_props because there is no __getStatic or __setStatic !!
# $prop_defaults adds a property for all object (key) and provide a default value (value)
# and is only in validating a new property on the object and not for storage.
public static $prop_defaults = array();
public $method = array();
public function __set($prop, $set) {
if (array_key_exists($prop,self::$prop_defaults)) {
$this->$prop = $set; # you could also apply so sort of setter filtering
} else return $this->_propHandler($prop);
}
public function __get($prop) {
if (array_key_exists($prop,self::$prop_defaults)) {
$this->$prop = self::$prop_defaults[$prop]; # set to default, return:
return $this->$prop;
} else return $this->_propHandler($prop);
}
public function __call($name, $args) {
if (array_key_exists($name,$this->methods))
return call_user_func ($this->methods[$name], $args);
else return $this->_methHandler($name);
}
public static function __callStatic($name, $args) {
if (array_key_exists($name,self::$static_methods))
return call_user_func (self::$static_methods[$name], $args);
else return $this->_methHandler($name);
}
protected function _propHandler($prop, $code=E_USER_ERROR) {
trigger_error("Invalid property: '$prop'", $code); return false;
}
protected function _methHandler($meth, $code=E_USER_ERROR) {
trigger_error("Invalid method: '$meth'", $code); return false;
}
}
$var = new Dynamic;
// $var->prop1 = "message\n";
// $var->prop2 = "message\n";
// $var->prop3 = "message\n";
// echo $var->prop3;
// Dynamic::$methods['my_method'] = function($arg) {
$var->methods['my_method'] = function($arg) use ($var) {
echo "the arg is $arg\m";
echo $var->it;
};
$var->my_method("the arg");
<?php
trait OpenClassTrait {
protected static $allow_props = true;
protected $methods = array();
protected static $static_methods = array();
public static function allowProp($arg, $default=null) {
if (is_bool($arg)): return (self::$allow_props = $arg)||true;
elseif (is_string($arg)): $arg = array($arg => $default);
elseif (!is_array($arg)):
return $this->fail("allowProp() Invalid Arg");
endif;
foreach ($arg as $k=>$v) {
if (!is_numeric($k)) $arr[$k] = $v;
else $arr[$v] = $default;
}
self::$allow_props = $arr;
}
public function addMethod($name, $callable) {
if (!is_callable($callable))
return $this->fail("addMethod() Arg 2 must be callable");
else $this->methods[$name] = $callable;
}
public function addStaticMethod($name, $callable) {
if (!is_callable($callable))
return $this->fail("addMethod() Arg 2 must be callable");
else $this->static_methods[$name] = $callable;
}
public function __set($prop, $set) {
if (is_bool(self::$allow_props)) {if (self::$allow_props) $let = true;}
elseif (array_key_exists($prop,self::$allow_props)) $let = true;
else $let = false;
if (!$let) return $this->fail("Invalid Property: '$prop'");
# you could apply some sort of setter filtering here
$this->$prop = $set;
}
public function __get($prop) {
if (is_bool(self::$allow_props)) {if (self::$allow_props) $let = true;}
elseif (array_key_exists($prop,self::$allow_props)) $let = true;
else $let = false;
if ($let) return $this->$prop = null;
else return $this->fail("Invalid Property: '$prop'");
}
public function __call($name, $args) {
if (array_key_exists($name,$this->methods))
return call_user_func ($this->methods[$name], $args);
else return $this->fail("Invalid Method: '$name'");
}
public static function __callStatic($name, $args) {
if (array_key_exists($name,self::$static_methods))
return call_user_func (self::$static_methods[$name], $args);
else return $this->fail("Invalid Method: '$name'");
}
protected function fail($msg, $code=E_USER_ERROR) {
trigger_error("$msg\n", $code); return false;
}
}
class OpenClass {
use OpenClassTrait;
}
$o = new OpenClass;
OpenClass::allowProp(['prop', 'other'], "yes");
echo $o->prop = 'hi';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment