Skip to content

Instantly share code, notes, and snippets.

@MarkBaker
Created January 29, 2016 09:49
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 MarkBaker/d7a55a70b7d14f7f4e1c to your computer and use it in GitHub Desktop.
Save MarkBaker/d7a55a70b7d14f7f4e1c to your computer and use it in GitHub Desktop.
Dynamic Instantiation of a class with optional Traits
<?php
class baseClass {
protected $a;
protected $b;
public function __construct($a, $b = null) {
$this->a = $a;
$this->b = $b;
}
public function sayWhat() {
echo $this->a, $this->b, PHP_EOL;
}
}
trait SayAB {
private $separator = ' ';
public function sayAB() {
echo $this->a, $this->separator, $this->b, PHP_EOL;
}
}
trait SayBA {
private $separator = ' ';
public function sayBA() {
echo $this->b, $this->separator, $this->a, PHP_EOL;
}
}
class AnonymousClassFactory {
private $className;
private $constructorArgs;
private $traits;
public function __construct($className, ...$args) {
$this->className = $className;
$this->constructorArgs = $args;
}
public function withTraits(...$traits) {
$this->traits = $traits;
return $this;
}
public function create() {
$eval = "new class(...\$this->constructorArgs) extends $this->className {" . PHP_EOL;
foreach($this->traits as $trait) {
$eval .= "use $trait;" . PHP_EOL;
}
$eval .= '}';
return eval("return $eval;");
}
}
$anonymous = (new AnonymousClassFactory('baseClass', 'hello', 'world'))
->withTraits('SayAB', 'SayBA')
->create();
$anonymous->sayWhat();
$anonymous->sayAB();
$anonymous->sayBA();
A really hacky method of adding Traits to a class on instantiation, but creating an anonymous class as a wrapper
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment