<?php
interface iface_dynamic_members{
    public function __call($name, $args);
    public function __set($name, $value);
    public function quietly_fail():bool;
}
trait trait_has_dynamic_members{
    public function __call($name, $args) {
        if (is_callable($this->$name)) {
            return call_user_func($this->$name, $args);
        }
        else {
            if($this->quietly_fail()===true){
                echo 'Method does not exist, but I do not mind.';
            }else{
                echo 'Method does not exist, I consider this a bug.';
            }
        }
    }
    public function __set($name, $value) {
        $this->$name = is_callable($value) ? $value->bindTo($this, $this): $value; }
}
abstract class MBR_ATTR{
    public static function is_a_walker(iface_dynamic_members $obj, ?string $walker_type='normal pace'){
        $obj->walker_type = $walker_type;
        $obj->walker_walk = function() {
            return "I am walking {$this->walker_type}.";
        };
    }
    public static function is_a_runner(iface_dynamic_members $obj, string $runner_type){
        $obj->runner_type = $runner_type;
        $obj->runner_run = function() {
            return "I am running {$this->runner_type}.";
        };
        self::is_a_walker($obj); }
}
class cls_partly_dynamic implements iface_dynamic_members{
    use trait_has_dynamic_members;
    public function quietly_fail():bool{
        return true;
    }
}
error_reporting(E_ALL & ~E_NOTICE); $obj_runner = new cls_partly_dynamic();
MBR_ATTR::is_a_runner($obj_runner, 'fast');
$obj_runner->runner_type = 'a bit slow';
$obj_walker = new cls_partly_dynamic();
MBR_ATTR::is_a_walker($obj_walker, 'slow');
$obj_walker->walker_type = 'super fast';
echo 'walker in action...' . '<br>';
echo $obj_walker->walker_walk() . '<br>';
echo '<br>';
echo 'runner in action...' . '<br>';
echo $obj_runner->walker_walk() . '<br>';
echo $obj_runner->runner_run() . '<br>';
echo $obj_runner->xxx() . '<br>'; ?>