рдмрд┐рдирд╛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ PHP рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдирд┐рдЬреА рдЧреБрдгреЛрдВ рддрдХ рдкрд╣реБрдБрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ

рдХреБрдЫ рд╣рдлреНрддреЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ ProxyManager рдореЗрдВ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдкрд░ рдХрд╛рдо рдХрд┐рдпрд╛ред рд╕рдорд╕реНрдпрд╛ рд╕рд░рд▓ рдереА: ReflectionClass рдФрд░ ReflectionProperty рдмрд╣реБрдд, рдмрд╣реБрдд, рдФрд░ рдмрд╣реБрдд рдзреАрдореА рд╣реИрдВ!
рдЗрд╕ рдЕрдзреНрдпрдпрди рдХрд╛ рдХрд╛рд░рдг рдЖрд░рдВрднрд┐рдХ рдХреЗ рдЙрдкрд░рд┐ рдХреЗ рдмрд┐рдирд╛ рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рд╛рдЗрдбреНрд░реЗрдЯрд░ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдореЗрд░рд╛ рдкреНрд░рдпрд╛рд╕ рд╣реИред

PHP 5.4 рдорджрдж!



PHP 5.4 рдиреЗ рд╣рдореЗрдВ рдХреНрд▓реЛрдЬрд░ рдФрд░ Closure#bind() рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдПрдкреАрдЖрдИ рджрд┐рдпрд╛ред
Closure#bind() рдореВрд▓ рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рд╡рд░реНрдЧ рдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рджрд╛рдпрд░реЗ рдХреЗ рд╕рд╛рде рдХреНрд▓реЛрдЬрд░ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рд╢рд╛рди рд╕реЗ! рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдореМрдЬреВрджрд╛ рд╡рд╕реНрддреБрдУрдВ рдореЗрдВ рдПрдкреАрдЖрдИ рдХреИрд╕реЗ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ!
рдЖрдЗрдП рдЕрдкрдиреА рдЬрд╝рд░реВрд░рддреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдХреЛ рддреЛрдбрд╝реЗрдВред
рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХреНрд╕реЗрд╕ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЛ рдкрд╣рд▓реЗ рд╣реА рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рд╕рдордЭрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рд╡реИрд╕реЗ рднреА рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛ред
рд╣рдо рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐ рдЪреЛрд░реА рдХрд░рддреЗ рд╣реИрдВ Kitchen#yummy :
 <?php class Kitchen { private $yummy = 'cake'; } 

рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдВрдж рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ:
 <?php $sweetsThief = function (Kitchen $kitchen) { return $kitchen->yummy; } 

рдЕрдм Kitchen рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдЪреЛрд░реА рдЪреЛрд░реА:
 <?php $kitchen = new Kitchen(); var_dump($sweetsThief($kitchen)); 

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдо $sweetsThief рдореЗрдВ рдПрдХ рдШрд╛рддрдХ рддреНрд░реБрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
 Fatal error: Cannot access private property Kitchen::$yummy in [...] on line [...] 

рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдЪреЛрд░ рдХреЛ Closure#bind() рд╕реЗ рдЕрдзрд┐рдХ рд╕реНрдорд╛рд░реНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ:
 <?php $kitchen = new Kitchen(); // Closure::bind()       $sweetsThief = Closure::bind($sweetsThief, null, $kitchen); var_dump($sweetsThief($kitchen)); 

рдЕ рдЫрд╛ !

рдмрдВрдж :: рдмрдВрдзрди рдмрдирд╛рдо рдкреНрд░рддрд┐рдмрд┐рдВрдм: рдкреНрд░рджрд░реНрд╢рди


рдореИрдВрдиреЗ 100,000 рдЖрд░рдВрднреАрдХрд░рдг рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдмрдирд╛рдпрд╛:
 <?php for ($i = 0; $i < 100000; $i += 1) { $sweetsThief = Closure::bind(function (Kitchen $kitchen) { return $kitchen->yummy; }, null, 'Kitchen'); } <?php for ($i = 0; $i < 100000; $i += 1) { $sweetsThief = new ReflectionProperty('Kitchen', 'yummy'); $sweetsThief->setAccessible(true); } 

рддрд╛рдЬрд╝рд╛ рд╕рдВрдХрд▓рд┐рдд PHP 5.5 (Ubuntu 13.04 amd64 рдмреЙрдХреНрд╕) рдкрд░, рдкрд╣рд▓рд╛ рдкрд░реАрдХреНрд╖рдг 0.325 рд╕реЗрдХрдВрдб рдФрд░ рджреВрд╕рд░рд╛ 0.658 рд▓рд┐рдпрд╛ рдЧрдпрд╛ ред

рдпрд╣рд╛рдБ рдкрд░рд╛рд╡рд░реНрддрди рдмрд╣реБрдд рдзреАрдорд╛ рд╣реИ ред (49%)

рд▓реЗрдХрд┐рди рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрд┐рд╕реА рдХреЛ рднреА рдПрдХ рд╣реА рдЪреАрдЬрд╝ рдХреЛ 100,000 рдмрд╛рд░ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рдХрдо рд╕реЗ рдХрдо рдореЗрд░реЗ рд▓рд┐рдП рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдХреНрдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪред рдореИрдВрдиреЗ рдпрд╣ рднреА рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛:
 <?php $kitchen = new Kitchen(); $sweetsThief = Closure::bind(function (Kitchen $kitchen) { return $kitchen->yummy; }, null, 'Kitchen'); for ($i = 0; $i < 100000; $i += 1) { $sweetsThief($kitchen); } <?php $kitchen = new Kitchen(); $sweetsThief = new ReflectionProperty('Kitchen', 'yummy'); $sweetsThief->setAccessible(true); for ($i = 0; $i < 100000; $i += 1) { $sweetsThief->getValue($kitchen); } 

рдкрд╣рд▓рд╛ рдкрд░реАрдХреНрд╖рдг ~ 0.110 рд╕реЗрдХрдВрдб рдФрд░ рджреВрд╕рд░рд╛ ~ 0.199 рд▓рд┐рдпрд╛ рдЧрдпрд╛!
рдпрд╣ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рддреЗрдЬ рд╣реИ, рдкреНрд░рднрд╛рд╡рд╢рд╛рд▓реА рд╣реИ! (55%)

рд▓рд┐рдВрдХ рджреНрд╡рд╛рд░рд╛ рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ


рдПрдХ рдФрд░ рдлрд╛рдпрджрд╛ рд╣реИ, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдмрдЬрд╛рдп рдХреНрд▓реЛрдЬрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рд▓рд┐рдВрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдЧреБрдгреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!
 <?php $sweetsThief = Closure::bind(function & (Kitchen $kitchen) { return $kitchen->yummy; }, null, $kitchen); $cake = & $sweetsThief($kitchen); $cake = 'lie'; var_dump('the cake is a ' . $sweetsThief($kitchen)); 


рдпреВрдирд┐рд╡рд░реНрд╕рд▓ рдПрдХреНрд╕реЗрд╕ рд╡рд┐рдзрд┐


рдЙрдкрд░реЛрдХреНрдд рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдо рдХрд┐рд╕реА рднреА рд╡рд╕реНрддреБ рдХреА рдХрд┐рд╕реА рднреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдЖрд╡рд░рдг рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:
 <?php $reader = function & ($object, $property) { $value = & Closure::bind(function & () use ($property) { return $this->$property; }, $object, $object)->__invoke(); return $value; }; $kitchen = new Kitchen(); $cake = & $reader($kitchen, 'cake'); $cake = 'sorry, I ate it!'; var_dump($kitchen); 

рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдЙрджрд╛рд╣рд░рдг ред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХрд┐рд╕реА рднреА рд╕рдВрдкрддреНрддрд┐, рдХрд╣реАрдВ рднреА рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рдВрджрд░реНрдн рддрдХ рдкрд╣реБрдВрдЪ рд╣реИред рд╣реБрд░реНрд░реЗ! рд╣рдордиреЗ рдлрд┐рд░ рдирд┐рдпрдо рддреЛрдбрд╝реЗ!

рдирд┐рд╖реНрдХрд░реНрд╖


рдПрдХ рдмрд╛рд░ рдлрд┐рд░, PHP рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдЕрдЪреНрдЫрд╛ рдФрд░ рдмреБрд░рд╛ рд╕рд╛рдмрд┐рдд рд╣реБрдЖред рдпрд╣ рдПрдХ рднрдпрд╛рдирдХ рднрд╛рд╖рд╛ рд╣реИ, рднрдпрд╛рдирдХ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рд╕рд╛рде, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рд▓реАрдЬрд╝ рдХреЗ рд╕рд╛рде рдирдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рд╣рдореЗрдВ рдкреНрд░рд╕рдиреНрди рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрд┐рд╕реА рднреА рднрд╛рд╖рд╛ рдкреНрд░рддрд┐рдмрдВрдз рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдореИрдВ рдЦреБрдж рдЗрд╕ рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдореБрдЭреЗ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреА рдирд┐рдЬреА рд╕рдВрдкрддреНрддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рдВрджрд░реНрдн рд╕реЗ, рдореИрдВ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХрд░реВрдВрдЧрд╛ред

рдЕрд╕реНрд╡реАрдХрд░рдг: рд╕рд╛рд╡рдзрд╛рдиреА рдХреЗ рд╕рд╛рде рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ!

Source: https://habr.com/ru/post/In186718/


All Articles