Created
November 7, 2018 14:11
-
-
Save chapterjason/6de70505206e5ebb107ef27f46cc8ea4 to your computer and use it in GitHub Desktop.
Dynamic PHP Methods
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 | |
/** | |
* 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