Skip to content

Instantly share code, notes, and snippets.

@kamekoopa
Created January 20, 2012 04:33
Show Gist options
  • Save kamekoopa/1645209 to your computer and use it in GitHub Desktop.
Save kamekoopa/1645209 to your computer and use it in GitHub Desktop.
動的にクラスを定義する何か
<?php
/**
* ClassBuilder::startBuild("Person")
* ->addProperty("protected", "name")
* ->addProperty("protected", "age")
* ->addProperty("protected", "gender")
* ->addMethod("public", '__construct($name, $age, $gender)',
* '$this->name = $name;'
* . '$this->age = $age;'
* . '$this->gender = $gender;'
* )
* ->addMethod("public", 'getName()',
* 'return $this->name;'
* )
* ->addMethod("public", 'getAge()',
* 'return $this->age;'
* )
* ->addMethod("public", 'getGender()',
* 'return $this->gender;'
* )
* ->addMethod("public", "__toString()",
* 'return sprintf("[name : %s, age : %s, gender : %s]", $this->name, $this->age, $this->gender);'
* )
* ->build();
*
* ClassBuilder::startBuild("Man")->extend("Person")
* ->addMethod("public", '__construct($name, $age)',
* 'parent::__construct($name, $age, "Male");'
* )
* ->build();
*
* ClassBuilder::startBuild("Woman")->extend("Person")
* ->addMethod("public", '__construct($name, $age)',
* 'parent::__construct($name, $age, "Female");'
* )
* ->build();
*
* $person = new Person("person", 20, "unknown");
* $man = new Man("man", 21);
* $woman = new Woman("woman", 22);
*
* echo $person . "\r\n";
* echo $man . "\r\n";
* echo $woman . "\r\n";
*/
class ClassBuilder {
private $className;
private $superClass;
private $interface;
private $properties = array();
private $metods = array();
public static function startBuild($className){
return new self($className);
}
private function __construct($className){
$this->className = $className;
}
public function extend($superClass){
$this->superClass = $superClass;
return $this;
}
public function implement($interface){
$this->interface = $interface;
return $this;
}
public function addProperty($scope, $name){
$this->properties[] = array(
"scope" => $scope,
"name" => $name,
);
return $this;
}
public function addMethod($scope, $signature, $contents){
$this->methods[] = array(
"scope" => $scope,
"signature" => $signature,
"contents" => $contents,
);
return $this;
}
public function toString(){
$className = $this->className;
$superClass = empty($this->superClass) ? "" : " extends {$this->superClass}";
$interface = empty($this->interface) ? "" : " implements {$this->interface}";
$properties = array();
foreach($this->properties as $property){
$scope = empty($method["scope"]) ? "" : $property["scope"];
$name = empty($method["name"]) ? "" : $property["name"] . ";";
$properties[] = sprintf("%s %s", $scope, $name);
}
$methods = array();
foreach($this->methods as $method){
$scope = empty($method["scope"]) ? "" : $method["scope"];
$signature = empty($method["signature"]) ? "" : $method["signature"];
$contents = empty($method["contents"]) ? "" : $method["contents"];
$methods[] = sprintf(
"%s function %s {" .
"%s" .
"}"
,$scope, $signature, $contents
);
}
$class = sprintf(
"class %s%s%s {"
. "%s"
. "%s"
. "}"
, $className, $superClass, $interface, implode(" ", $properties), implode(" ", $methods)
);
return $class;
}
public function build(){
eval( $this->toString() );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment