PHP5.4 Advent Calendar 2011Ì7úÚÅ·BðúÍ@madapaja³ñÌuPHP5.4+ ÅJªsíêÄ¢é BEAR.Sunday t[[N𮩵ÄÝévŵ½B
³Ä³ÄF³ñAjbgeXgµÄÜ·©H PHPàeXgÌCuª[ÀµÄ«Ä¨èAJobW100%ÉîMðRâµÄ¢éûར±Æŵå¤B
jbgeXgÅ¢é̪Aprivate/protected\bhÅ·BO©çÄ×È¢ÌÅAÊÌû@ÅÍeXgūܹñB(protectedÍKÈ_~[ÌTuNXðìÁÄ»±©çeXgÅ«Ü·ªA¿åÁÆÊ|Å·B)
Ü RÅ·BO©çÄ×È¢æ¤ÉprivateɵĢéÌÅAÈPÉÄ×½çtÉ¢éí¯Å·Bµ©µÈªçAprivate\bhàO©çÄñÅeXgÅ«½ûªJÍÍ©Çéŵå¤B±ÌLÅÍPHPÅprivateðeXg·éû@É¢ÄÜÆßÄ¢«Ü·B
¡ÜÅ
ãq·éReflectionMethod::setAccessibleªoê·éPHP5.3.2ÈOÅÍAprivateÌÇðËj·éû@Í"ö®ÉÍ" èܹñŵ½B
ÌÍrunkitÆ¢¤ÏÔextensionðg¤±ÆÅeXgÅ«½»¤Å·ªA±Ìrunkit³ñAÅßÌPHPo[WÉǵĨç¸A÷Ég¢É¢óÛðó¯Ü·(PHP4ÁÛ¢µÍC)B\bhÌANZX Àð¼ÚÏX·éæ¤È@\ÍÈ¢ÌÅAKÈ_~[NXÉ\bhðRs[µÄeXg·é´¶Åµå¤©H
¼ÌprivateeXgû@ƵÄÍAá¦ÎC++ÌÖfÌô¶A#define private public
ð^·éû@ª èÜ·BrequireÌãíèÉevalðg¢A\[XR[h𫷦ĵܦ΢¢B
<?php //require_once 'Klass.php'; //requireÌãíèÉ eval('?'.'>' .str_replace( array('private','protected'), 'public', file_get_contents('Klass.php'))); $obj = new Klass(); $obj->methodA(); //private¾Á½ÆµÄàÄ×é͸
evalÈçprivateðpublicÉu«·¦Ä©çR[hð]¿³¹é±ÆªÅ«Ü·B ÆÍÊÉpublic\bhðeXg·é´oÅeXgR[hð¯Ü·B
½¾A±Ìû@ͳâèÈÌŢ©âèª èÜ·B
- NXè`ÆeXgR[hªÊt@CÉÈÁÄ¢éKvª é
- \¶ð͵ȢPÈu·ÈÌÅAeval()ÅNXðè`µÄ¢éæ¤ÈgbL[ÈR[hÉÍKpÅ«È¢B
- R[hÉßÜ꽶ñÌ"private"àu«·íÁĵܤ
- requireµ½æÅXÉrequireµÄ¢½êAu·³êÈ¢BeNXªprotectedÌÜÜÈÌÉpublicÅI[o[Chµæ¤Æ·éÆG[ÉÈÁÄÀsÅ«È¢B
ÇAKpÅ«éR[hÍÀçêĵܢܷB»ñÈí¯ÅAprivate\bhÌeXgÍúßélཀྵÁ½ÌÅÍȢŵ天H@±ÌóµÍPHP5.3ª[X³êÄ©çàµÎçÍÏíèܹñŵ½B
ReflectionMethod::setAccessible(PHP5.3.2È~)
»µÄA5.3.2ÅâÁÆAprivateÌö®ÈËjû@ªÅ«Üµ½BReflectionMethod::setAccessibleðg¤Æprivate\bhÉO©çANZXÅ«éæ¤ÉÈèÜ·B
<?php class Klass { private function methodA(){ echo 'private methodA!',PHP_EOL; } } $obj = new Klass(); $methodA = new ReflectionMethod($obj, 'methodA'); $methodA->setAccessible(true); $methodA->invoke(); //privateÈ͸ÌmethodAªÄ×éII
êAnew ReflectionMethodµÄsetAccessible(true)µÄÆèÔÍ©©èÜ·ªA±¿çÍö®èiÈÌÅæÙÇÌeval()Éæéû@ÌfbgÍSÄðÁ³êĢܷB
±êÅprivate\bhÌeXgâèÍAêÌððÝܵ½B
PHP5.4ÌClosure::bind()
³ÄA±±ÅbÍIíèܹñBâÁÆPHP5.4ÌbÅ·BK©sK©A5.4Åà¤êÂprivateðËj·éû@ªÇÁ³êĢܷB»êªClosure::bindÅ·B
TÁƬ³êÄ¢éæ¤ÈCàµÜ·ªAu³¼ÖÉÀèÀsReLXgð®IÉÏXÅ«évÆ¢¤¦Ü¶¢@\Å·Bu¦ÁH ±êAÅ«¿áÁÄ¢¢ÌHvÆ·«Ôµ½ÈéxB
Closure::bindðg¤Æ±ñÈR[hªÀsÅ«Ü·B
<?php class Klass { private function methodA(){ echo 'private methodA!'; } } Closure::bind(function(){ var_dump($this); $obj = new Klass(); $obj->methodA(); }, null, 'Klass')->__invoke(); //----------------- //NULL //private methodA! //Æoͳêé
NXÌÅÈ¢ÌÉAmethodA()ªÄ×Ä¢é±Æªí©èÜ·B
Closure::bindÍAæ2øÉ$thisÉZbg·éIuWFNgAæ3øÉÀsReLXgðwèµAæ1ø̳¼ÖÌRs[ðԵܷBc¤[ñAྪﵢŷËB
͵åÁÄྷéÆA±ÌubNÉ©ê½R[hÍAæ3øÉwèµ½NXÌÅÀs³êéÁÄƱëŵ天BãLÌR[hÅÍ"Klass"ÌÅÀs³êÄ¢é(Ʃȳêé)½ßAKlassÌprivateÈ\bhAvpeBÉANZXÅ«Ä¢éÌÅ·B
³Á«ÌReflectionMethodÆä×ÄÝéÆAtNVÍ\bh²ÆEvpeB²ÆÉnewµÄsetAccessible(true)µÈ¯ê΢¯Ü¹ñŵ½ªAClosure::bindðg¤êÍubNð¾¯Å¢¢ÌÅAÆÄàÇÝâ·¢ÌÅÍȢŵ天B
eXgR[hÍ"ÇÝâ·³"ªåÏd³êéªìÅ·BDSLŶ@ðWrapµ½¾¯ÅÊÌCuð¼æÁÄ¢éà̪ é®ç¢Å·BÜ A»ê¾¯eXgR[hÆ¢¤ÌÍêâ·AÇÝÉÈèⷢƢ¤±Æŵå¤B
िåÁÆïÌIÉAPHPUnitIÈeXgCuðg¤ê¾Æ±ñÈC[WÉÈèÜ·B$thisÁĢĢéÌÉ$thisÅÍÈ$objÌReLXgÅÀs³êÄ¢éÆ¢¤AsvcÈóµÅ·B
<?php class Klass { private function methodA(){ return 'private methodA!'; } } class KlassTest { public function testMethodA() { Closure::bind(function(){ $obj = new Klass(); $res = $obj->methodA(); $this->assertTrue($res === 'private methodA!'); }, $this, 'Klass')->__invoke(); } public function assertTrue($bool) { echo ($bool) ? 'OK!' : 'NG!', PHP_EOL; } } $test = new KlassTest(); $test->testMethodA();
ÊíÌpublicèÌeXgR[hÆär·éÆAá¢ÍO¤ð¢ÁÄ¢éubN̶ݾ¯Å·B±êÈçAbp[Æ©©ÈÄà[ª±ê¾¯Åg¦éÆv¢Ü·B
Closure::bindÍevalâgotoƯ¶xÅD«èÅ«éë¯È@\Å·ªAp·éÆÊ¢Æv¢Ü·BPHP5.4ªÒ¿µ¢Å·ËB
¾úÍ@do_aki³ñÅ·B
keyword: PHP AdventCalendar