Skip to content

Instantly share code, notes, and snippets.

@chapterjason
Created November 7, 2018 14:11
Show Gist options
  • Save chapterjason/6de70505206e5ebb107ef27f46cc8ea4 to your computer and use it in GitHub Desktop.
Save chapterjason/6de70505206e5ebb107ef27f46cc8ea4 to your computer and use it in GitHub Desktop.
Dynamic PHP Methods
<?php
/**
* Copyright Jason Schilling
**/
interface DynamicMethodsAwareInterface
{
}
trait DynamicMethodsAwareTrait
{
protected static $methods = [];
public static function addMethod($name, $method)
{
if (!is_callable($method))
{
throw new Error("addMethod parameter $method musst be a callable!");
}
self::$methods[$name] = $method;
}
public function __call($name, $arguments)
{
if (isset(self::$methods[$name]))
{
$method = self::$methods[$name];
$method = \Closure::bind($method, $this, get_class());
return call_user_func_array($method, $arguments);
}
throw new Error("Call to undefined method " . get_class($this) . "::" . $name);
}
}
class Bar
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
}
class Foo implements DynamicMethodsAwareInterface
{
use DynamicMethodsAwareTrait;
protected $bars = [];
}
$foo = new Foo;
function addManyMethods($className, $name)
{
$classReflection = new ReflectionClass($className);
var_dump($classReflection);
if ($classReflection->implementsInterface(DynamicMethodsAwareInterface::class))
{
$singular = $name;
$plural = $name . 's';
$className::addMethod("get" . ucfirst($plural) , function () use ($plural)
{
return $this->{$plural};
});
$className::addMethod("set" . ucfirst($plural) , function ($items) use ($plural)
{
$this->{$plural} = $items;
return $this;
});
$className::addMethod("add" . ucfirst($singular) , function ($item) use ($plural)
{
$this->{$plural}[] = $item;
return $this;
});
$className::addMethod("remove" . ucfirst($singular) , function ($item) use ($plural)
{
$key = array_search($item, $this->{$plural}, true);
if ($key === false)
{
return $this;
}
unset($this->{$plural}[$key]);
return $this;
});
}
}
addManyMethods(Foo::class , "bar");
$foo->addBar(new Bar('He'));
$foo->addBar(new Bar('She'));
var_dump($foo->getBars());
$bar = new Bar('It');
$foo->setBars([$bar, new Bar('Her') ]);
var_dump($foo->getBars());
$foo->removeBar($bar);
var_dump($foo->getBars());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment