ããæ©ãç§ã®
èªè»¢è»ãã¬ãŒã ã¯ãŒã¯ã§ORMã®åäœãå®è£
ããããã«ãRubyã®mixinã®ããã«ããŸãã¯CïŒã®æ¡åŒµã¡ãœãããšããŠïŒãŸãã¯PHPã®å°æ¥ã®ããŒãžã§ã³ã§ã¯trait / graftãšããŠïŒåäœãããã®ãå¿
èŠã§ããPHPã§äžçŽç©ãå®è£
ããæ¹æ³ã楜ãã¿ã«æ¥œãã¿ãŸããã äžçŽç©ãäœã§ãããããããªãå Žåã¯ãåé¡ã§ã¯ãããŸããããã¹ãŠã説æããŸãã
PHPã§ã®äžçŽç©ã®å®è£
ãšãããããå®è£
ã§ããå°ããªã©ã€ãã©ãªã®ããã°ã©ãã³ã°ã«ã€ããŠã®è°è«ã§ç§ããã©ããŒããŠãã ããã ãã®èšäºã¯ãPHPã®åå¿è
ããã³äžçŽã®éçºè
ã察象ãšããŠããŸãïŒäž»ãªããšã¯ãOOPã«ç²ŸéããŠããããšã§ãïŒã ãã®éçšã§ãã¯ã©ã¹ã䜿çšããŠPHP 5.3ãæäœããéã®è€éãã«ã€ããŠãå°ãééããŸããããã°ããããŠããææããä¿®æ£ããããšãææ¡ããŸãã ãŸããããªãã®æ¹å€ã«å¯Ÿããç§ã®è§£æ±ºçãæäŸããŸãã è¯ãèªæžãããŠãã ããã
äžçŽç©ãšã¯äœã§ããïŒ
æ··åç©ã¯ãã¡ãœãããšããããã£ãä»ã®ã¯ã©ã¹ã«åã«å
¬éããã¯ã©ã¹ã§ãã ã¯ã©ã¹ã«ä»ã®ã¯ã©ã¹ãæ··åšãããããšã¯ãå€éç¶æ¿ããšãã¥ã¬ãŒãããããã®åãªããªãã·ã§ã³ã§ãããPHPã§ã¯å®è£
ãããŠããªããšæ³å®ã§ããŸãã ããããããããããã«ãæ§æãPHPã«äŒŒãæ¬äŒŒã³ãŒãã䜿çšããå°ããªäŸã瀺ããŸãã
<ïŒphp
mixin Timeable {
private $ timeStarted;
ãã©ã€ããŒã$ timeStopped;
public function startïŒïŒ{$ timeStarted = timeïŒïŒ; }
public function stopïŒïŒ{$ timeStopped = timeïŒïŒ; }
public function getElapsedïŒïŒ{return $ timeStopped-$ timeStarted}
}
mixin Dumpable {
public function dumpïŒïŒ{var_dumpïŒ$ thisïŒ; }
}
TimeableãDumpableãæ··åããMyClassã¯ã©ã¹{
ãããªãã¯é¢æ°helloïŒïŒ{}
}
$ a = new MyClassïŒïŒ;
$ a-> startïŒïŒ;
ç¡ç ïŒ250ïŒ;
$ a-> stopïŒïŒ;
echo $ a-> getElapsedïŒïŒ;
$ a-> dumpïŒïŒ;
ïŒ>
ã¢ã€ãã¢ã¯æ確ã§ããïŒ äžçŽç©ã¯ãã¯ã©ã¹ãããããã¹ãŠããããã«ç¶æ¿ããããã®ããã«ãåã«æ©èœãã¯ã©ã¹ã«è¿œå ããŸãã ãã ãããããã¯æ··åãããŠããã¯ã©ã¹ã®ã¡ã³ããŒãæäœã§ããŸãã ããã¯ãPHPã§å®è£
ããæ©èœã®äžçš®ã§ãã
èªåã§ã¿ã¹ã¯ãèšå®ããŸãããã
- ç¹å®ã®ã¯ã©ã¹ã®äžçŽç©ã®æ©èœãç¹å®ã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«æ··åããæ©èœãå®çŸããå¿
èŠããããŸãã
- äžçŽç©ã¯ã©ã¹ã¯ãæ··åãããã¯ã©ã¹ã®åã«ããŒãããªãã§ãã ããã äžèšã®äŸã§ã¯ãç䌌æ§æã䜿çšããããããã¯ã©ã¹å®£èšã§äžçŽç©ã¯ã©ã¹ãçŽæ¥å®çŸ©ã§ããŸããã ãããããã®æ¹æ³ã«ã¯æ¬ ç¹ããããŸãã ããã°ã©ã ã®éçšã§ãã·ã¹ãã ã®ã¯ã©ã¹ã«äžçŽç©ãšããŠæ©èœãããã©ã°ã€ã³ãè¿œå ããå¿
èŠãããå Žåã¯ã©ããªããŸããïŒ ãã®å Žåãåæåã¹ã¯ãªããã®ã©ããã§ãã¹ãŠã®äžçŽç©ã宣èšã§ããŸããããã®ãããªå®£èšãã¯ã©ã¹ã®ããŒãã«ã€ãªãããªãããšãéèŠã§ãã
- æ··åç©ãäœããã®ã¯ã©ã¹ã«æ··åãããå Žåãããã¯ããã®æ©èœããã®ã¯ã©ã¹ã®åå«ã¯ã©ã¹ã§å©çšå¯èœã§ããããšãæå³ããŸãã ããã«ããããããããªããžã§ã¯ãæåèšèªã䜿çšããŠãããããã¯è«ççã§ãã
- å®è£
æã«ã¯ãç¹ã«ã·ã¹ãã ã§å€ãã®äžçŽç©ã䜿çšãããŠããå ŽåãäžçŽç©ã®ã¯ã©ã¹ã®ã¡ã³ããŒã®äœ¿çšã¯ããŸãæå¶ãã¹ãã§ã¯ãªãããšãèæ
®ããããšããå§ãããŸãã
- äžçŽç©ã䜿çšããããã«æ¢åã®ã¯ã©ã¹ãå€æŽããå Žåãæ¢åã®ã·ã¹ãã ãåèšèšããå¿
èŠã¯ãããŸããã ãã®çµæãããã¯ãæœè±¡ã¯ã©ã¹ããç¶æ¿ããããšã«å ããŠãä»ã®ã¯ã©ã¹ããããèªäœã«æ©èœãããã¯ã¹ããããã«ã¯ã©ã¹ã«æããããã«ãå¥ã®å¯èœæ§ããªããã°ãªããªãããšãæå³ããŸãã
- äžçŽç©ã®ãããªãã¯ããããã£ãšã¡ãœããã¯ããã¹ãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãä»ããŠå©çšã§ããããã«ããå¿
èŠããããŸãïŒä»¥äžã§ã¯ãããèªäœã§ããã€ãã®äžçŽç©ãéçŽã§ããããããã¢ã°ãªã²ãŒã¿ãŒããšåŒã³ãŸãïŒã ãã©ã€ããŒãã§ä¿è·ãããŠãããã®ã¯ãäžçŽç©èªäœã«ã®ã¿è¡šç€ºãããå¿
èŠããããŸãã
- æ··åç©ã¯ããã®ã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã®é ããã£ãŒã«ããšä¿è·ããããã£ãŒã«ãã«ãã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸãïŒãã®ãããªèŠä»¶ãèšå®ãããšããC ++ãPHPããŸãã¯CïŒã«ååšãããšããæå³ã§é ããä¿è·ãããããããã£ããªãRubyã«çŠç¹ãåœãŠãŸãããã¯ã©ã¹ã®ä»»æã®ãã£ãŒã«ãã«é©çšã§ããŸãããæ··åç©ã¯æ°ããåäœãè¿œå ããå¯èœæ§ããããããã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ããã®ä¿è·ãããæ
å ±ãå¿
èŠã«ãªãå ŽåããããŸãã
ã¬ãžã¹ããªãèšèšããŠããŸãã
èãçŽããŠã¿ãŸãããã ã·ã¹ãã ã®ç°ãªãã¯ã©ã¹ã«ç°ãªãäžçŽç©ãè¿œå ãããå ŽåããããŸãã ã€ãŸããã©ãã«ãã©ã®ã¯ã©ã¹ã®äžçŽç©ãæ··å
¥ããŠãããã«é¢ããæ
å ±ãä¿åããå¿
èŠããããŸãã ãããžã§ã¯ãã®ãã®ãããªæ
å ±ã¯ã°ããŒãã«ã§ãããã©ãããã§ãã¢ã¯ã»ã¹ã§ããå¿
èŠããããŸãã ãããã£ãŠããã®ãããªã¹ãã¬ãŒãžãå®è£
ããããã«ãéçã¯ã©ã¹ãéžæããŸããïŒPHPã«ã¯CïŒã®ããã«éçã¯ã©ã¹ã¯ãããŸãããéçã¯ã©ã¹ãšã¯ãã€ã³ã¹ã¿ã³ã¹åããå¿
èŠã®ãªãã¯ã©ã¹ãæå³ããŸãããã¹ãŠã®æ©èœã¯ãã¯ã©ã¹ïŒã å°ããªäœæ¥ãšããŠãã·ã³ã°ã«ãã³ã䜿çšããå¿
èŠããªãããã«ãã¬ãžã¹ããªãåèšèšããããšããå§ãããŸãïŒèå³ãããå Žåã¯ãèšäºãæåŸãŸã§èªãã åŸïŒã
äžèšãããã¬ãžã¹ããªã¯ã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã®äžçŽç©ãç»é²ã§ããã¯ãã§ãã ãããŠããå°ãé«ããç¹å®ã®ã¯ã©ã¹ã«äžçŽãç»é²ããå Žåããã®äžçŽã®æ©èœã¯ãã¹ãŠã®åå«ã¯ã©ã¹ã«æ··åããå¿
èŠããããšèšããŸããã ç»é²æã«ããã«ç¥å
ã¯ã©ã¹ã®ãªã¹ããååŸããããšã¯ã§ããŸããïŒã¯ã©ã¹ã®ããŒããé¿ããå¿
èŠããããã¯ã©ã¹éå±€ã®æ€æ»ã«ã¯ãããå¿
èŠã§ãïŒã ãã®ããšãããåŸã§å¿
èŠãªãšãã«å¯Ÿå¿é¢ä¿ã®ãªã¹ãïŒã¯ã©ã¹=>äžçŽç©ã®ãªã¹ãïŒãäœæããŸãã ããã«ãã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã®æ°ããã€ã³ã¹ã¿ã³ã¹ãäœæãããšãã«ãªã¹ããåæ§ç¯ãããªãããã«ããã®ãããªãªã¹ãããã£ãã·ã¥ããå¿
èŠããããŸãã
class Registry { private static $registeredMixins = array(); public static function register($className, $mixinClassName) { $mixinClassNames = func_get_args(); unset($mixinClassNames[0]); foreach ($mixinClassNames as $mixinClassName) { self::$registeredMixins[$className][] = $mixinClassName; } self::$classNameToMixinCache = array(); } }
ç»é²æ©èœã¯éåžžã«ã·ã³ãã«ã§ããããšãå€æããŸããã ã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã®ååãšäžçŽç©ã®ãªã¹ãã圌女ã«äžããŸãã 䟿å®äžãäžçŽç©ã®ãªã¹ãã¯ã³ã³ãã§ç€ºãããšãã§ããŸãã Func_get_argsïŒïŒããããåŠçããŸãïŒå¿
èŠã«å¿ããŠãäžçŽç©ã®ãªã¹ããé
åãšããŠæå®ããããã®é©åãªãµããŒããè¿œå ããŸãïŒã 次ã«ããã®ã¯ã©ã¹ã®äžçŽç©ã®ãªã¹ãã«åäžçŽç©ãè¿œå ããŸãã ãŸããé¢æ°ã®æåŸã®æåŸã®åŒã³åºãã¯ãã£ãã·ã¥ãã¯ãªã¢ããŸããããã¯ãç¹å®ã®ã¯ã©ã¹ã®äžçŽæ§ãç»é²ãããšããã®ãã¹ãŠã®åå«ã«ããã£ãã·ã¥ãè¿œå ããããã£ãã·ã¥ã®åæ§ç¯ãå¿
èŠã«ãªãããã§ãã
ãã£ãã·ã³ã°é¢æ°ãæžããŸãããã ã¯ã©ã¹ãšãããã«ç»é²ãããäžçŽç©ã®ãªã¹ãã調ã¹ãåãäžçŽç©ã®ãªã¹ãã§æå®ããããã¹ãŠã®åå«ã¯ã©ã¹ãè¿œå ããå¿
èŠããããŸãã çµæã¯ãã£ãã·ã¥ã§ãã
ãã£ãã·ã³ã°é¢æ°ã«ã¯ããã®ã¯ã©ã¹ã®ç¥å
ã®ãªã¹ããåãåãé¢æ°ãå¿
èŠã§ãã
private static $classNameToMixinCache = array(); private static function getAncestors($className) { $classes = array($className); while (($className = get_parent_class($className)) !== false) { $classes[] = $className; } return $classes; } private static function precacheMixinListForClass($className) { if (isset(self::$classNameToMixinCache[$className])) { return; } $ancestors = self::getAncestors($className); $result = array(); foreach ($ancestors as $ancestor) { if (isset(self::$registeredMixins[$ancestor])) { $result = array_merge($result, self::$registeredMixins[$ancestor]); } } self::$classNameToMixinCache[$className] = array_unique($result); }
ãã®é¢æ°ã¯ãæå®ãããã¯ã©ã¹ã®äžçŽç©ã®ãªã¹ãã®ã¿ããã£ãã·ã¥ã«è¿œå ããããšã«æ³šæããŠãã ããã ãã£ãã·ã¥ã®å
容ã®ã»ãšãã©ãå¿
èŠã«ãªãããšã¯ãªãããããã£ãã·ã¥å
šäœãããã«ã¯äœæããŸããã ãã£ãã·ã¥ãæ§ç¯ããåã«ããã§ã«ãããè¡ã£ãŠãããã©ããã確èªããŸããã
ããã§ãç¹å®ã®ã¯ã©ã¹ã®äžçŽç©ã®ãªã¹ããååŸããå¿
èŠãããå Žåããã®é¢æ°ã䜿çšã§ããŸãã
public static function getMixinsFor($className) { self::precacheMixinListForClass($className); return self::$classNameToMixinCache[$className]; }
次ã®ã¹ãããã«é²ã¿ãŸãã ç§ãã¡ãã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã¡ãœãããåŒã³åºãããã®ã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã¡ãœããã§ã¯ãªããããã€ãã®äžçŽç©ã§å®çŸ©ãããŠãããšæ³åããŠãã ããã äœãããå¿
èŠããããŸããïŒ ãã®ã¯ã©ã¹ã®äžçŽç©ã®ãªã¹ããååŸãããããã調ã¹ãŠãå¿
èŠãªã¡ãœããããããã®ããããã§å®çŸ©ãããŠãããã©ããã確èªããå¿
èŠããããŸãã
æ··åã¯ã¯ã©ã¹ã®æ¬è³ªã§ããããã次ã®ããã«ããŸãã
private static $methodLookupCache = array(); public static function getMixinNameByMethodName($className, $methodName) { if (isset(self::$methodLookupCache[$className][$methodName])) { return self::$methodLookupCache[$className][$methodName]; } self::precacheMixinListForClass($className); foreach (self::$classNameToMixinCache[$className] as $mixin) { if (method_exists($mixin, $methodName)) { self::$methodLookupCache[$className][$methodName] = $mixin; return $mixin; } } throw new MemberNotFoundException("$className has no mixed method $methodName()!"); }
ã€ãŸãããã£ãã·ã¥ã«ãã®ã¯ã©ã¹ãšã¡ãœããåã®ãšã³ããªãæ¢ã«ããå ŽåãåçŽã«ããããè¿ããŸãã ããã§ãªãå Žåã¯ããã£ãã·ã¥ãããã®ã¯ã©ã¹ã®äžçŽç©ã®ãªã¹ããååŸãããããããã€ãã¹ããŠãå®è£
ãå¿
èŠãªã¡ãœããããããã©ããã確èªããŸãã ãã®å Žåããã£ãã·ã¥ã«è¿œå ããäžçŽç©ã®ååãè¿ããŸãã äœãèŠã€ãããªãå ŽåãäŸå€ãã¹ããŒããŸãã
ããããã£ã«å¯ŸããŠãŸã£ããåããªãã·ã§ã³ãååŸãããŸãã èªåã§æžãããšããå§ãããŸãã
以äžã§ãã ã¬ãžã¹ããªãå®è£
ããŸããã äžçŽç©ã¯ã©ã¹ã®ããã°ã©ãã³ã°ã«é²ã¿ãŸãã
æ··åç©ãããã°ã©ã ããŸãã
ã ãããæ··åç©ã ã©ããªäžçŽç©ïŒ æ··åç©ã¯æ®éã®ã¯ã©ã¹ã§ãã 圌ã¯å¥ã®ã¯ã©ã¹ã®ãã£ãŒã«ããæäœããæ¹æ³ãç¥ã£ãŠããŸãã ãããŠããã®ä»ã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã§æž¡ãããšãè«ççã§ãã
class Base { protected $_owningClassInstance; protected $_owningClassName; public function __construct($owningClassInstance) { $this->_owningClassInstance = $owningClassInstance; $this->_owningClassName = get_class($owningClassInstance); } }
ç§ã®ãããžã§ã¯ãã§ã¯ãMixinsåå空éã«å±ããŠãããããããå
·äœçã«ååãä»ããå¿
èŠã¯ãªããããããŒã¹ã®äžçŽã¯ã©ã¹ãBaseãšåä»ããŸããã ãã ãã奜ããªååãä»ããããšãã§ããŸãã
å€æ°owningClassInstanceãä»ããŠããããªãã¯ãã£ãŒã«ããšã¡ãœãããçŽæ¥æäœã§ããŸãã ããããé ããä¿è·ãããç¶æ
ã§ã¯ããªãã¬ã¯ã·ã§ã³ãä»ããŠäœæ¥ããå¿
èŠããããŸãã è€éãªããšã¯äœããããŸããã é¢æ°ã®ãã¹ãŠã®å®çŸ©ã瀺ããŸãã
protected $_owningPropertyReflectionCache; protected $_owningMethodReflectionCache; protected function getProtected($name) { if (! isset($this->_owningPropertyReflectionCache[$name])) { $property = new \ReflectionProperty($this->_owningClassName, $name); $property->setAccessible(true); $this->_owningPropertyReflectionCache[$name] = $property; } return $this->_owningPropertyReflectionCache[$name]->getValue($this->_owningClassInstance); } protected function setProtected($name, $value) { if (! isset($this->_owningPropertyReflectionCache[$name])) { $property = new \ReflectionProperty($this->_owningClassName, $name); $property->setAccessible(true); $this->_owningPropertyReflectionCache[$name] = $property; } $this->_owningPropertyReflectionCache[$name]->setValue($this->_owningClassInstance, $value); } protected function invokeProtected($name, $parameters) { $method = new \ReflectionMethod($this->_owningClassName, $name); $method->setAccessible(true); $parameters = func_get_args(); unset($parameters[0]); $method->invokeArgs($this->_owningClassInstance, $parameters); }
ããã§ã¯ããªãã¬ã¯ã·ã§ã³ã®ããã«ã·ã¹ãã ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŠåžžã«æ§æããªãããã«ããã£ãã·ã¥ãåã³æå¹ã«ããŠããããšã«æ³šæããŠãã ããã ã¡ã¢ãªæ¶è²»ãåæžããããã«ãå¿
èŠã«å¿ããŠãã£ãã·ã¥ãç Žæ£ã§ããŸãã
ã¬ãžã¹ããªã¯ã©ã¹ã§äœ¿çšããmethod_existsïŒïŒããã³property_existsïŒïŒé¢æ°ã¯ããããªãã¯åãšãšãã«æå®ãããååã®é ããä¿è·ãããé¢æ°ãæã£ãŠããäžçŽç©ããã§ãã¯ããããšã«æ¢ã«æ°ã¥ããŠãããããããŸããã ããã«ãããã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã¯ãé衚瀺ãŸãã¯ä¿è·ãšããŠå®çŸ©ãããŠããå Žåãåãååã®é¢æ°ããè©Šè¡ãã§ããããã«ãªããŸãã ãã®çµæããŸã ãšã©ãŒãçºçããŸãããæ瀺çã«ãããè¡ãããšã奜ã¿ãŸãã
public function __call($name, array $arguments) { throw new MemberNotFoundException( "Method $name is not defined or is not accessible in mixin \"" . get_class() . "\""); } public function __get($name) { throw new MemberNotFoundException( "Property $name is not defined or is not accessible in mixin \"" . get_class() . "\""); } public function __set($name, $value) { throw new MemberNotFoundException( "Property $name is not defined or is not accessible in mixin \"" . get_class() . "\""); }
å°ããªã¿ã¹ã¯ãšããŠãã¬ãžã¹ããªã¯ã©ã¹ã®ãã®ãããªäžé©åãªåäœãä¿®æ£ããŠã¿ãŠãã ããã ããã«ã以åã¯å¥ã®ååã§é衚瀺ãŸãã¯ä¿è·ãããŠããååã§ãããªãã¯ãªäžçŽç©ã¡ãœãããåŒã³åºãããšãã§ããªããªããŸãã
ã㮠以äžã§ãã æ··åç©ã¯ããã«é£ã¹ãããŸãã æåŸã®ã¹ããã-äžçŽç©ãæ··åããããã®ãã©ãããã©ãŒã ã®å®è£
-ã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã ãããç§ãã¡ãä»ããããšã§ãã
ã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ãäœæããŸãã
ã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã¯äœãã§ããŸããïŒ åœŒã¯ãäžçŽç©ã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãä¿åãããããã®ã¡ãœãããåŒã³åºãæ¹æ³ãç¥ã£ãŠããŸãã ããŠãããããã£ãåç
§ããŠãã ããã ãã®åäœã¯ãPHPã®ãããžãã¯ãã¡ãœããã䜿çšããŠå®è£
ããŸãã
class Aggregator { protected $_mixins; protected $_className; public function __construct($aggregatorClassInstance = false) { $this->_className = $aggregatorClassInstance ? get_class($aggregatorClassInstance) : get_class($this); $mixinNames = Registry::getMixinsFor($this->_className); foreach ($mixinNames as $mixinName) { $this->_mixins[$mixinName] = new $mixinName($aggregatorClassInstance ? $aggregatorClassInstance : $this); } } }
ã³ã³ã¹ãã©ã¯ã¿ãŒã³ãŒãã§ã¯ãã¯ã©ã¹ã®äžçŽç©ã®ãªã¹ããååŸããããããã«ãŒãã§åŠçããŠã€ã³ã¹ã¿ã³ã¹ãäœæããŸãã
å€æ°$ aggregatorClassInstanceã¯ãAggregatorã¯ã©ã¹ããã¯ã©ã¹ãç¶æ¿ããå¿
èŠããªãããšãä¿èšŒããã®ã«åœ¹ç«ã¡ãŸãã Aggregatorã¯ã©ã¹ãå¥ã®ã¯ã©ã¹ã«å«ãããã®ä»ã®ã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«çãã$ aggregatorClassInstanceãã©ã¡ãŒã¿ãŒã䜿çšããŠã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºãããšãã§ããŸãã ãããã£ãŠãããããããšã§ããã®ææè
ã¯ã©ã¹ã®äžçŽç©ã®ãªã¹ããååŸããã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã®å¯Ÿå¿ããã€ã³ã¹ã¿ã³ã¹ãäžçŽç©ã«æž¡ããŸãã
äžèšã®èª¬æãè€éããããšæãããå Žåã¯ãåé¡ã§ã¯ãããŸããã å°ãäœãæ»ã£ãŠãäŸããããŸãã ç¶æ¿ã®äŸãã³ã³ããžã·ã§ã³ã®äŸãšã©ã®ããã«ç°ãªããã©ã®ããã«æ©èœããããã芧ãã ããã
ãéæ³ã®æ¹æ³ããå®çŸããŸãã
public function __call($name, array $arguments) { return call_user_func_array(array($this->_mixins[Registry::getMixinNameByMethodName($this->_className, $name)], $name), $arguments); } public function __get($name) { return $this->_mixins[Registry::getMixinNameByPropertyName($this->_className, $name)]->$name; } public function __set($name, $value) { $this->_mixins[Registry::getMixinNameByPropertyName($this->_className, $name)]->$name = $value; } public function __isset($name) { return isset($this->_mixins[Registry::getMixinNameByPropertyName($this->_className, $name)]->$name); }
åããžãã¯ã¡ãœããã¯ãæ
å ±ãååŸããããã«ã¬ãžã¹ããªã«ã¢ã¯ã»ã¹ããŸãã ãã¹ãŠãã·ã³ãã«ã§ãã
䜿çšããäŸå€ã¯ã©ã¹ã¯æ¬¡ã®ããã«ãªããŸãã
class MemberNotFoundException extends \Exception {}
ããã€ãã®äŸãèŠãŠã¿ãŸãããã
æåã«ãç¶æ¿ã䜿çšããåŸæ¥ã®ã¹ããŒã ã®å ŽåïŒ
class MixinAggregatorSample extends Mixins\Aggregator { } class MixinHello extends Mixins\Base { protected $inaccessible; public $text = "I am a text!\r\n"; public function hello() { echo ("Hello from mixin!\r\n"); } } Mixins\Registry::register("MixinAggregatorSample", "MixinHello"); $a = new MixinAggregatorSample(); $a->hello();
å
å«åè·¯ãèŠãŠã¿ãŸãããã
class MixinAggregatorSample { protected $_aggregator; public function __construct() { $this->_aggregator = new Mixins\Aggregator($this); } public function __call($name, $arguments) { return $this->_aggregator->__call($name, $arguments); } } class MixinHello extends Mixins\Base { public function hello() { echo ("Hellp from mixin!"); } } Mixins\Registry::register("MixinAggregatorSample", "MixinHello"); $a = new MixinAggregatorSample(); $a->hello();
éããããããŸããïŒ å«ããå Žåãæ©èœã倱ãããšãªããã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ãä»ã®ã¯ã©ã¹ããèªç±ã«ç¶æ¿ã§ããŸãã ãã¡ãããéåžžã®äœ¿çšã§ã¯ã__ callïŒïŒã ãã§ãªãããã¹ãŠã®ããžãã¯ã¡ãœãããå®è£
ããå¿
èŠããããŸãã
æ§èœ
çµæã®ã©ã€ãã©ãªã®é床ã枬å®ããŸããã 枬å®ã¯éåžžã«è¿äŒŒããŠããããªãŒãã³IDEãWinampãããã³æ³å®ããããã¹ãŠã®æ©èœãåããããŒã ã³ã³ãã¥ãŒã¿ãŒã§å®è¡ãããŸãã
ãã€ãã£ãæéïŒ0.57831501960754
æéã«ããååïŒ1.5227220058441
æ··åæéïŒ7.5425450801849
æéã®åæ ïŒ12.221807956696
- ãã€ãã£ã-PHPã§ã¯ã©ã¹ã¡ãœãããçŽæ¥åŒã³åºãæé
- Byname-ååã§ã¯ã©ã¹ã¡ãœãããåŒã³åºãæé$ myClass-> $ methodName
- æ··å-æ··åã¡ãœããåŒã³åºãæé
- Reflection-Reflectionãä»ããŠã¯ã©ã¹ã®ããããã£ãå€æŽããæ··åã¡ãœãããåŒã³åºããšãã ã€ãŸã =æ··å+åå°ã
- æéã¯800,000ã³ãŒã«ã®ç§åäœã§äžããããŸãã
ãã®ãããªã¢ãããŒãã倧èŠæš¡ãªãããžã§ã¯ãã§äœ¿çšã§ããããã«ãäžèšã®æ°å€ã¯ååã«åãå
¥ãããããšæããŸãã ååãšããŠãäžçŽãªã¡ãœããã¯ã¹ã¯ãªããã§äœååãåŒã³åºããããã¡ãœãããåŒã³åºãã®ã«0.7ãã€ã¯ãç§ã«å¯ŸããŠ10ãã€ã¯ãç§ã¯ãã€ãã£ãã¡ãœããã«ã¯éåžžã«åãå
¥ãããããªãã·ã§ã³ã§ãã ç¹ã«ã倧éã®ããã¹ããããŒã¿ããŒã¹ãžã®ã¯ãšãªã®å®è¡ãªã©ãhtmlspecialcharsïŒïŒã«è²»ããããæéãéåžžã«é·ããšèãããšç¹ã«ããã§ãã
ã»ãšãã©ãã¹ãŠã®å Žæã§ãããã·ã¥ãããPHPé
åã«åºã¥ãããã£ãã·ã¥ã䜿çšããŠãããããäžçŽç©ãã¢ã°ãªã²ãŒã¿ãŒã¯ã©ã¹ã®æ°ãå¢ããŠããããã©ãŒãã³ã¹ã¯ããã»ã©äœäžããŸããã ãããã誰ããå¿
èŠãªãã¹ããè¡ãå Žåãç§ã¯éåžžã«å¹žãã«ãªããŸãã
ãšãããŒã°
ãã®èšäºã«é¢ããããªãã®æ¹å€ãèããŠããããã§ãã ç§ã¯ãã®è³æããã¹ãŠã®èªè
ãç解ã§ããããã«ãããã©ããã«ç¹ã«èå³ããããŸãã
ãã¡ããããã®èšäºã¯å®å
šãæ£ç¢ºããŸãã¯ãšã©ãŒã®ãªãããšãç®çãšãããã®ã§ã¯ãããŸããã ããªããç§ãä¿®æ£ããŠããããæ¬åœã«æè¬ããŠããŸãã
ããã§çµæã®ã©ã€ãã©ãªã®ã³ãŒããåºããŸããã ãã¡ããããããžã§ã¯ãã¯ãã¬ãŒãã³ã°ãããžã§ã¯ãã§ãããå®éã®ãããžã§ã¯ãã§äœ¿çšããåã«ãæ
éã«èããŠãã¹ãŠããã¹ããã䟡å€ããããŸãã åãã¯ã©ã¹å
ã®åãååã®ãããªãã¯ã¡ãœãããæã€ããã€ãã®äžçŽç©ãªã©ãããã€ãã®åé¡ã®ããåé¡ãååšããŸãã
PHPã®äžçŽç©ã®ãããã¯ã«èå³ãããå Žåã¯ãã°ãŒã°ã«ããå§ãããŸãã