
Badooã¯ãPHP 7ã«åãæ¿ããæåã®äŒæ¥ã®1ã€ã§ãã-æè¿
ããã«ã€ããŠæžããã°ããã§ãã ãã®èšäºã§ã¯ããã¹ãã€ã³ãã©ã¹ãã©ã¯ãã£ã®å€æŽã«ã€ããŠèª¬æããSoftMocksãšåŒã°ããrunkitæ¡åŒµæ©èœçšã«éçºãã眮æã«ã€ããŠããã«èª¬æããããšãçŽæããŸããã
ãœããã¢ãã¯
SoftMocksã®ã¢ã€ãã¢ã¯éåžžã«ã·ã³ãã«ã§ãã¿ã€ãã«ã«åæ ãããŠããŸããçŽç²ãªPHPã§ãã»ãã³ãã£ã¯ã¹ã§æãäºææ§ã®ããrunkitã®ã¢ããã°ãå®è£
ããå¿
èŠããããŸãã ããã§Softã¯ãZend APIããã®ä»ã®ããŒãã³ã¢ã䜿çšããã«ãPHPã³ã¢å
ã§ã¯ãªãããã®äžã«å®è£
ãããããšã匷調ããŠããŸãã ãããçŽç²ãªPHPã§ãããšããäºå®ã¯ãæ¡åŒµæ©èœãæ°ããããŒãžã§ã³ã®Zend APIã§æžãæããŠãã»ãã³ãã£ã¯ã¹ã®ããŸããŸãªåŸ®åŠãªåå ã«ããæ°çŸäžã®ãã°ããã£ããããã®ã§ã¯ãªããæ°ããããŒãžã§ã³ã®PHPã«ç°¡åã«åãæ¿ããŠãæ°ããæ§æã®ãµããŒããè¿œå ã§ããããšãæå³ããŸãã
çŽç²ãªPHPã§ã¯ãããã¯
godebug ãgo test -coverãªã©ãå€ãã®GoããŒã«ãåäœããã®ãšåãæ¹æ³ã§å®è¡ã§ããŸãã -ç§ãã¡ã®å Žåãã³ãŒãã®èªåæžãæã-ãã®å Žã§ããã€ã³ã¯ã«ãŒãžã§ã³ãã®çŽåã«ã ã€ã³ã¿ãŒãããã§ã¯ã
GoïŒã®äžã§å®è¡ããã
AspectMockãã¹ã
ãã¬ãŒã ã¯ãŒã¯ãèŠã€ããããšãã§ããŸã
ã AOP㯠ãã³ãŒããæžãæããAOPã¹ã¿ã€ã«ã§èšè¿°ããæ©èœãæäŸããŸãã ãã®ãã¬ãŒã ã¯ãŒã¯ã¯åªããŠããŸãããç§ãã¡ã®ç¶æ³ã§ã¯runkitãå®å
šã«çœ®ãæãããã®ã§ã¯ãªãããããã®ã©ã€ãã©ãªã®ã€ã¡ãŒãžãšé¡äŒŒæ§ã§ç¬èªã®ãœãªã¥ãŒã·ã§ã³ãèšè¿°ããããšã«ããŸããã æ®å¿µãªãããåè¿°ã®ãã¬ãŒã ã¯ãŒã¯ã¯ãæ©èœãã¡ãœãããå³åº§ã«ååããæ©èœãæäŸããŠããŸããïŒã€ãŸããç¹å®ã®æ©èœãååããæå³ãäºåã«çºè¡šããããšã¯ãããŸããïŒã ç¬èªã®ã¹ã³ãŒãããããŸãããããã¯runkitããã³uopzã®åäœãšã¯ç°ãªããŸãã
runkitã¯äœãããŸããïŒ
PHPã®Runkitæ¡åŒµæ©èœã䜿çšãããšãPHPã³ãŒãã®å®è¡äžã«ããªããžã§ã¯ããé¢æ°ãã¡ãœãããããã³å®æ°ã®ç¶æ
ã«å¯ŸããŠããŸããŸãªæäœãçŽæ¥å®è¡ã§ããŸãã
ããã¥ã¡ã³ãã®äŸïŒhttp://php.net/manual/en/function.runkit-function-redefine.phpïŒã
ãã¹ãããã°ã©ã ïŒ
<?php function testme() { echo "Original Testme Implementation\n"; } testme(); runkit_function_redefine('testme','','echo "New Testme Implementation\n";'); testme();
ãã¹ãããã°ã©ã ã®åºåïŒ
Original Testme Implementation New Testme Implementation
æ©èœãã¹ããåäœãã¹ãã§ã¯ããã®ãããªã©ã³ãããæ©èœãéåžžã«åºã䜿çšããŠããŸãã åºæ¬çã«ããã®æ¡åŒµæ©èœã®äœ¿çšã¯ãã¡ãœãããé¢æ°ãããã³å®æ°å€ã®å®è£
ã®ä»£æ¿ã«éå®ãããŸãã
ã©ã€ãã©ãªã®API
äºåã®ã¢ããŠã³ã¹ãªãã§ãæ©èœãšã¡ãœããããã®å Žã§åå®çŸ©ããæ©èœãåããåãæ©èœãååŸããããšèããŠããŸãã runkitã®ä»£ããã«SoftMocksã䜿çšãããšãããã°ã©ã ã¯æ¬¡ã®ããã«ãªããŸãïŒåãäŸïŒã
<?php
ãã®äŸãå®è¡ããã³ãã³ãã¯æ¬¡ã®ãšããã§ãã
$ php -r 'require("init.inc"); require(SoftMocks::rewrite("test.php"));'
ãã¹ãããã°ã©ã ã®åºåã¯ãrunkitã®åºåãšåãã§ãã
init.incãã¡ã€ã«ã«ã¯ãSoftMocksã¯ã©ã¹ãåæåããããã®ã³ãŒããå«ãŸããŠããã次ã®ããã«ãªããŸãïŒãã¡ã€ã«ã®ç¹å®ã®åœ¢åŒã¯ã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠç°ãªããŸãïŒã
<?php
å®è£
ã¢ã€ãã¢
æåã®ã¢ã€ãã¢ã¯éåžžã«ã·ã³ãã«ã§ããïŒã¡ãœãããšé¢æ°ã®ãã¹ãŠã®åŒã³åºããå®æ°ã®åŒã³åºããã©ãããŒã®åŒã³åºããã©ããããŠãç¹å®ã®ã¡ãœãããšé¢æ°ã®ã¢ãã¯ãªããžã§ã¯ãããããã©ããã確èªã§ããŸãã
ãããã£ãŠããã®ãããªããã®ã³ãŒã
class A extends B { public function test($a, $b) { parent::test($a, $b); $c = file_get_contents("something.txt"); return $c; } }
ããã«ãªããŸãïŒ
class A extends B { public function test($a, $b) { \QA\SoftMocks::call([parent::class, 'test'], [$a, $b]); $c = \QA\SoftMocks::call('file_get_contents', ['something.txt']); return $c; } }
SoftMocks :: callïŒïŒã¡ãœããã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
public static function call($func, $args) { if (!self::isMocked($func)) { return call_user_func_array($func, $args); } return self::callMocks($func, $args); }
å®è£
ã®éå§ïŒååž°çãªæžãæããå«ãã
æåã«ãããã³ãã³ã³ãããŒã©ãŒã§ããŸãã¯PHPUnitãã¹ãã®å Žåã¯bootstrap.phpã§SoftMocksã®äœ¿çšãæå¹ã«ã§ããããã«ã1ã€ã®ããšããã§ããªãã·ã³ãã«ãªããŒãµãŒãäœæããŸããã ããã¹ãŠã®ãã¡ã€ã«ã¯ããŒãµãŒã«ãã£ãŠååž°çã«æžãæããããŸãã
äŸïŒ
ããã§ãautoload.phpã¯èªåããŒããããžã§ã¯ãã®ã¯ã©ã¹ãããŒãããå¿
èŠãªãã®ãã¹ãŠãç»é²ããã³åæåããŸããå Žåã«ãã£ãŠã¯ãã€ã³ã¯ã«ãŒãïŒ...ïŒã䜿çšããŠä»ã®ãã¡ã€ã«ãããŒãããŸãã ããã³ãã³ã³ãããŒã©ãŒãå«ãå
ã®ãã¡ã€ã«ãå¥ã®å ŽæïŒããšãã°ãfront-orig.phpïŒã«ç§»åããããã«çœ®ãæããå¿
èŠããããŸãã
ããŒãµãŒãæž¡ããšãfront-orig.phpãã¡ã€ã«ã¯æ¬¡ã®ããã«ãªããŸãã
SoftMocks :: rewriteïŒ$ filenameïŒã¡ãœããã¯ãã¡ã€ã«ãäžæžãããrequireãincludeãmethodã®åŒã³åºããªã©ãã©ãããŒã®åŒã³åºãã«çœ®ãæããŸãã ãã®é¢æ°ã®æ»ãå€ã¯ãæ¢ã«ã©ãããããã³ãŒããå«ããã¡ã€ã«ãžã®æ°ãããã¹ã§ãããé¢æ°ãã¡ãœãããå®æ°ã®å€ããã®å Žã§åå®çŸ©ã§ããŸãã
ããšãã°ã
front-orig.php
ã¯
/tmp/mocks/<hash-code>/front-orig.php_<version>
ã«å€æãããŸãã ã³ã³ãã€ã«ããããã¡ã€ã«ãžã®ãã¹ã§ã<hash-code>ã¯ãã¡ã€ã«ã®å
容ãšãã¹ã«åºã¥ããŠèšç®ãããŸããããã«ãããã³ã³ãã€ã«ããããã¡ã€ã«ããã£ãã·ã¥ãããã¡ã€ã«ã®è§£æãšæžãæãã®æé ã1åã ãå®è¡ã§ããŸãã
æåã¯ãæ¬æ Œçãªæ§æ解æã®è€éããç解ããããã«ãincludeãšrequireã®ã¿ãæžãçŽãããã£ãã®ã§ãã PHPã§ã¯ããã®ãããªæ§é ã«ãã©ã±ããã䜿çšããªãããšãã§ããŸãïŒã€ãŸãã
require("a.php"))
代ããã«
require("a.php"))
require "a.php";
èšè¿°ã§ããŸã
require("a.php"))
ããŸããåŒãšä»ã®é¢æ°ã®åŒã³åºãããµããŒãããŸãã ããã«ããããå
å«ç©ãã眮ãæããæãåçŽãªã¿ã¹ã¯ãå¿
èŠä»¥äžã«é£ãããªããŸãã __FILE__ããã³__DIR__å®æ°ããããŸãããããã®å€ã¯ããã¡ã€ã«ã®å Žæã«å¿ããŠåçã«å€åããŸãã
include(dirname(__DIR__) . â/something.phpâ);
ãããªã³ãŒããããèŠãããŸã
include(dirname(__DIR__) . â/something.phpâ);
ãããã³__DIR__å®æ°ãš__FILE__å®æ°ã®åŒã³åºãã¯ããããã®å
容ã«çœ®ãæããå¿
èŠããããŸãã
å¥ã®äžå¿«ãªåé¡ã¯ãã€ã³ã¯ã«ãŒãã§çžå¯Ÿãã¹ã䜿çšã§ããããšã§ãïŒ
require "a.php"
ïŒããããã£ãŠãinclude_pathèšå®ã«æ³šæãæããçŸåšã®ãã£ã¬ã¯ããªïŒ "ã"ïŒã®å€ããœãŒã¹ã®ãã£ã¬ã¯ããªã§ã¯ãªããæžãæãããããã¡ã€ã«ã
token_get_allïŒïŒå¯ŸPHPããŒãµãŒ
ããŒãµãŒã®æåã®ããŒãžã§ã³ã¯ãtoken_get_allïŒïŒé¢æ°ã䜿çšããããšããŸããããã®é¢æ°ã¯éåžžã«é«éã«æ©èœãããã¡ã€ã«å
ã®ããŒã¯ã³ã®é
åãè¿ããŸãã åé¡ã¯ãSoftMocks :: callïŒïŒã§é¢æ°åŒã³åºããã©ããããå Žåã«å¿
èŠãªããã«ãé¢æ°ã®ãã¹ããããåŒæ°ã解æããããšãããã«ã¯åŒæ°ãªã¹ããé
åã§çœ®ãæããããšã¯éåžžã«é£ããããšã§ãã
ãããã£ãŠã
PHP ParserãšããNikita Popovã®ã©ã€ãã©ãªã䜿çšããŸããã ãã®ã©ã€ãã©ãªã¯ãtoken_get_allïŒïŒã«ãã£ãŠè¿ãããããŒã¯ã³ã®ãªã¹ãã«åºã¥ããŠASTããªãŒãæ§ç¯ã§ããŸãããŸããããªãŒãèµ°æ»ããŠå€æŽããããã®äŸ¿å©ãªããŒã«ãæäŸããŸãã ãã®ã©ã€ãã©ãªã«ãããå¿
èŠãªãã®ãç°¡åã«å®è£
ã§ããŸãã
æ®å¿µãªãããããŒãµãŒã«ã¯æ¬ ç¹ããããŸãã
- ããã©ãŒãã³ã¹ã®äœäžïŒãã³ãããŒã¯ã«ãããšããã¡ã€ã«ã®è§£æã«ã¯token_get_allïŒïŒã®çŽ15åã®æéãããããŸãã
- å
ã®è¡çªå·ãç¶æããªãããå€æŽãããããªãŒãå°å·ããŠæ»ãããšãã§ããªãã
ã©ã€ãã©ãªãPHPã«ãããããæåã®åé¡ã解決ããã®ãé£ããå Žåã¯ããç®±ããåºããŠããã«ãæäŸãããããªã³ã¿ãæ¡åŒµããããšã§ã2çªç®ã®æ¬ ç¹ã解æ¶ããŸããã ãã®ç®çã®ããã«ãåºåãã¡ã€ã«ããçŸãããããšã¯ããã»ã©éèŠã§ã¯ãããŸããã§ãããPHPUnitã®ãšã©ãŒã¡ãã»ãŒãžãšã³ãŒãã«ãã¬ããžã®èšç®ããã¹ãã®åœ±é¿ãåããªãããã«ãå
ã®è¡çªå·ãæ倧ã«ä¿ã€ã ãã§ããã
æçµå®è£
PHPããŒãµãŒã«åºã¥ããŠãç§ãã¡ã¯åœåã®ç®çãæ£ç¢ºã«å®è¡ãããããã¿ã€ãããã°ããäœæããŸãããããã¯ãã¬ã€ã€ãŒã®åŒã³åºãã§ã¡ãœãããšé¢æ°ã®åŒã³åºããã©ããããŸãã æ®å¿µãªãããã¡ãœããã®å Žåããã®ã¢ãããŒãã«ã¯å€ãã®åé¡ããããŸããã
- call_user_func *ãã¡ããªãŒã¯privateããã³protectedã¡ãœããã®åŒã³åºããèš±å¯ããªããããããã©ãŒãã³ã¹ã«ããŸã圱é¿ããªãReflectionã䜿çšããå¿
èŠããããŸã
- 芪ã¡ãœãããåŒã³åºãã«ã¯ããç¹å¥ãªã¹ããªãŒãããžãã¯ãã«é Œãå¿
èŠããããŸãã芪ã¡ãœãããžã®åŒã³åºãã¯parent
parent::call_something(...)
ãšããŠèšé²ãããŸãããåŒã³åºãã¯å®éã«ã¯éçã§ã¯ãªãåçã§ãã ããã«ãéçã¯ã©ã¹ã®å€ã¯ä¿æããå¿
èŠãããã芪ã¯ã©ã¹ãæãå¿
èŠã¯ãããŸããã æ®å¿µãªãããReflectionãä»ããŠåŒã³åºããšãã«çŸåšã®éçã³ã³ããã¹ããä¿åããç°¡åãªæ¹æ³ã¯èŠã€ãããŸããã§ãã-ãã®ã¡ãœããã¯ãŸã ååšããªãå¯èœæ§ããããŸãã - åžžã«setAccessibleïŒtrueïŒã䜿çšããŠReflectionãä»ããŠã¡ãœãããåŒã³åºããããå®éã«ã¯åžžã«privateããã³protectedã¡ãœããããããªãã¯ã§ãããã®ããã«åŒã³åºããŸããããå®éã®ãã³ãŒãã§ã¯å®è¡æã«èŽåœçãªãšã©ãŒã«ã€ãªããå¯èœæ§ããããŸãã ãã¹ããããã³ãŒãã®åäœãå€æŽããŸãããããã¯èš±å¯ãããŠããŸããã
- ãã®æ¹æ³ã§ãããžãã¯ãã¡ãœããã®å®è£
ã眮ãæããããšã¯ã§ããŸãããããšãã°ã__ constructã__ getã__ setã__ cloneã__ wakeupãªã©ã§ãã
ãã®çµæãåã¡ãœããå®çŸ©ã®åã«è¿œå ã®ã³ãŒããæ¿å
¥ããããšã«ãããã¯ã©ã¹ã¡ãœããã®ã¢ãã¯ãªããžã§ã¯ããå®è£
ãããšããçµè«ã«éããŸããã äŸ
public function doSomething($a) { return $a > 5; }
次ã®ããã«ãªããŸãã
public function doSomething($a) { if (SoftMocks::isMocked(...)) { return eval(SoftMocks::getMockCode(...)); } return $a > 5; }
ã¡ãœããåŒã³åºããã©ããããŸããããããã§ãé¢æ°ã«å¯ŸããŠãããè¡ããŸãã ãã®ã¢ãããŒãã§ã¯ãçµã¿èŸŒã¿ã¯ã©ã¹ã®ã¡ãœãããã€ã³ã¿ãŒã»ããããããšã¯ã§ããŸããããé©ãã¹ãããšã«ããã®æ©èœã¯ãŸã å¿
èŠãããŸããã§ããã èå³æ·±ãããšã«ãAspectMockã©ã€ãã©ãªã¯ãã¡ãœããã¢ãã¯ãªããžã§ã¯ãã«å¯ŸããŠåæ§ã®ã¢ãããŒãã䜿çšããŸãã
é¢æ°ã䜿çšããå Žåãåé¡ããããŸãã
- get_called_classïŒïŒãªã©ãäžéšã®é¢æ°ã¯çŸåšã®ã³ã³ããã¹ãã«äŸåããŸãã
static
ïŒæååïŒãself
ãªã©ã®å€ã¯é¢æ°ã«æž¡ãããšãã§ããé¢æ°ã¯ã©ãããŒãä»ããŠåŒã³åºããããããé¢æ°ã¯ãããã®ããŒã¯ãŒãã«å¯ŸããŠç°ãªãå€ãååŸããŸãã ãã®ãããªå Žåããã¹ããããã³ãŒããå€æŽããŠãé¢æ°ãæååã§ã¯ãªãã¯ã©ã¹åãããšãã°static::class
ã§ã¯ãªãstatic::class
ã«æž¡ãããããã«ããå¿
èŠãããstatic
ã- preg_replace_callbackãªã©ã®ã³ãŒã«ããã¯ãåŒã³åºãããšãã§ããé¢æ°ã¯ããã©ã€ããŒãã¡ãœãããåŒã³åºãããšãã§ããŸãã preg_replace_callbacké¢æ°ã®å®éã®åŒã³åºãã¯SoftMocksã¯ã©ã¹ããè¡ããããããã¢ã¯ã»ã¹ãšã©ãŒãçºçãããã®ã³ã³ããã¹ãããã®ãã©ã€ããŒãã¡ãœããã«ã¢ã¯ã»ã¹ã§ããªããªããŸãã ãã®åé¡ã®è§£æ±ºçã¯ãããšãã°
array($this, 'callback')
代ããã«å¿åé¢æ°ãæž¡ããªã©ãã³ãŒããæžãæããããšã§ãã
ãããã®åé¡ã®ã»ãšãã©ã解決ããããã«ã奜転ãããåžžã«çŽæ¥åŒã³åºãããé¢æ°ã®ããã©ãã¯ãªã¹ããããµããŒãããŸããã ãããã®ããã€ãã次ã«ç€ºããŸããget_called_classãget_parent_classãfunc_get_argsãusortãarray_walk_recursiveãextractãcompactãget_object_varsã ãããã®é¢æ°ã¯ãSoftMocksã䜿çšããŠçœ®ãæããããšã¯ã§ããŸããã
ã°ããŒãã«å®æ°ãšã¯ã©ã¹å®æ°ã®ã€ã³ã¿ãŒã»ããã¯éåžžã«ç°¡åã§ããå®æ°ãžã®ãã¹ãŠã®åŒã³åºããé¢æ°åŒã³åºãã«çœ®ãæããŸãã å¯äžã®äŸå€ã¯ãå®æ°ãé¢æ°ãŸãã¯ã¯ã©ã¹ããããã£ã®åŒæ°ã§ããã©ã«ãå€ãšããŠç€ºãããŠããå Žåã§ãã ã€ãŸãã次ã®å Žæãæžãæããããšã¯ã§ããŸããã
class A { private $b = SOME_CONST; }
ããã©ãŒãã³ã¹äžã®çç±ãããå®æ°trueãfalseãããã³nullãã©ããããªãããšã決å®ããŸããã ããã¯ãrunkitãšã¯ç°ãªããSoftMocksã§ã¯redefineConstant
redefineConstant("true", false);
ã§ããªãããšãæå³ã
redefineConstant("true", false);
ã
æ§èœ
SoftMocksã¯çŽç²ãªPHPã§äœæãããŠãããããããã©ãŒãã³ã¹ã¯runkitãããå£ããšäºæ³ãããŸãã å®éãSoftMocksã¯åŒã³åºãæã«ã©ã³ã¿ã€ã ãã£ãã·ã¥ããªã»ããããå¿
èŠããããªã©ã®åé¡ã«æ©ãŸãããŠããªãããããã¹ãã¯ããéããããå®å®ããŠåæ Œãå§ããŸããã ã©ã€ãã©ãªã¯ãããŒããããã¯ã©ã¹ãšé¢æ°ã®æ°ãå¢ãããŠãããã©ãŒãã³ã¹ãäœäžããªãããããã®å Žåã®å
šäœçãªããã©ãŒãã³ã¹ã¯ãããã«åäžããããšãããããŸããã
SoftMocksé¢æ°ããŸã£ãã䜿çšããã«ãæžãæããããã³ãŒããå®è¡ãããšãæšå®ã«ãããšããã®ããã©ãŒãã³ã¹ã¯çŽ3åäœäžããŸãã äžè¬ã«ãããã©ãŒãã³ã¹äžã®çç±ãšã»ãã¥ãªãã£äžã®çç±ã®äž¡æ¹ã§ãSoftMocksãåäœãã¹ãã«äœ¿çšãããã®ã©ã€ãã©ãªãå®çšŒåã«äœ¿çšããªãããšããå§ãããŸããã©ã€ãã©ãªã¯äžæãã¡ã€ã«ãäœæããWebã³ã³ããã¹ãããæžã蟌ã¿å¯èœãªãã£ã¬ã¯ããªããã€ã³ã¯ã«ãŒãããŸãã
PHPUnitãšã®çµ±å
ãå«ãŸããããã¡ã€ã«ãžã®ãã¹ã眮ãæãããšãå
ã®ãã¡ã€ã«ã§ã¯ãªãèªåçæããããã¡ã€ã«ãåå ã§ãããã¯ãã¬ãŒã¹ãèªã¿åãäžèœã«ãªããŸãã ãŸããPHPUnitèªäœããã¡ã€ã«ãã¢ããããŒããããœãŒã¹ã³ãŒããæžãæããªãããããã¹ããã¡ã€ã«ã§å®çŸ©ãããé¢æ°ãšã¡ãœããã眮ãæããããšãã§ããŸããã
ãããã®åé¡ã解決ããããã«ãPHPUnitã®pull-requestãæºåããŸããïŒ
github.com/sebastianbergmann/phpunit/pull/2116ãããã«
SoftMocksãããžã§ã¯ãã¯GitHubã®
github.com/badoo/soft-mocksã§å
¥æã§ããŸãã
Nikita Popovã®PHP Parserã䜿çšããŸããããã¯GitHubã§ãå
¥æã§ããŸãïŒ
github.com/nikic/PHP-Parser ã
ãã®å Žã§ã³ãŒããæžãæãããšãã«ããµãŒãããŒãã£ã®æ¡åŒµæ©èœã䜿çšããã«ãçŽç²ãªPHPã§é¢æ°ããŠãŒã¶ãŒã¡ãœãããããã³å®æ°ã®å®è£
ã眮ãæããããšãã§ããããã«ããŸããã ç§ãã¡ã®ã±ãŒã¹ã§ã¯ãrunkitãå®å
šã«åãé€ããPHP 7ã®60,000ãŠããããã¹ãã®ã¹ã€ãŒãå
šäœããå®è¡ãããèŠã€ãã£ãéäºææ§ãä¿®æ£ããŸããïŒããããããèŠã€ãããŸããããããã®ããã€ãã¯ãPHP 7ã®éçºããŒãžã§ã³ã§ãšã©ãŒéçºè
ã«å ±åããŸããïŒã
Badoo.comã¯çŸåšPHP 7ãå®è¡ããŠããŸãããç¹ã«SoftMocksã®éçºã®ãããã§ããããéæããããšãã§ããŸããã ããªãã®çµéšãç§ãã¡ãšåãããã«ååãã«ãªãããšãé¡ã£ãŠããŸãã
ãããã¹ããããŠãã ããïŒ
Yuri Nasretdinovãã·ãã¢PHPéçºè