рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ PHP рдореЗрдВ рдбрд┐рдЬрд╛рдЗрди рдкреИрдЯрд░реНрди - рд╕рд┐рдВрдЧреНрд▓рдЯрди рдХреЛ рддреЛрдбрд╝рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрд╛ рдерд╛ред рд▓реЗрдЦ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдкреИрдЯрд░реНрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдПрдХ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣рд╛ рдерд╛: рдХреНрдпрд╛ Closure::bind()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреНрд▓рд╛рд╕ рдХреЗ рдирдП рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджрд┐рдП рдмрд┐рдирд╛ PHP рдореЗрдВ рд╕рд┐рдВрдЧрд▓рдЯрди рдмрдирд╛рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИ?

рдореИрдВ рдХрдИ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рдЖрдпрд╛, рд▓реЗрдХрд┐рди рдЙрдирдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдЬрд╛рдиреЗ рдХреЗ рд░рд╛рд╕реНрддреЗ рднреА рдЦреЛрдЬреЗред рдпрд╣ рдореБрдЭреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рдЧ рд░рд╣рд╛ рдерд╛ рдХрд┐ рдПрдХ рдирдпрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдПрдХ рд╡рд┐рдЪрд╛рд░ рдЖрдпрд╛ рдФрд░ рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ред
рдпрд╣рд╛рдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдФрд░ рд▓рд┐рдВрдХ ред рдЪрд▓реЛ рдЗрд╕реЗ рдЕрд▓рдЧ рд▓реЗ:
<?php final class Singleton { public static function getInstance() { static $instance; if (null === $instance) { $instance = new self(); } return $instance; } private function __construct() { static $hasInstance = false; if ($hasInstance) { \trigger_error('Class is already instantiated', \E_USER_ERROR); } $hasInstance = true; } private function __clone() { \trigger_error('Class could not be cloned', \E_USER_ERROR); } private function __wakeup() { \trigger_error('Class could not be deserialized', \E_USER_ERROR); } } $s1 = Singleton::getInstance(); \var_dump(\spl_object_id($s1)); $createNewInstance = function () { return new self(); }; $newInstanceClosure = Closure::bind($createNewInstance, $s1, Singleton::class);
рд╣рдо $instance
рд╡реИрд░рд┐рдПрдмрд▓ рдХреЛ getInstance()
рд╡рд┐рдзрд┐ рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдо рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ self
рдФрд░ static
рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдПрдХреНрд╕реЗрд╕ рди рдХрд░ рд╕рдХреЗрдВред
рдХреНрд▓рд╛рд╕ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ, рд╣рдо рдПрдХ рд╕реНрдЯреИрдЯрд┐рдХ рд╡реЗрд░рд┐рдПрдмрд▓ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬреЛ рдмреВрд▓рд┐рдпрди рд╡реИрд▓реНрдпреВ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИред рдПрдХ рдирдИ рд╡рд╕реНрддреБ рдмрдирд╛рддреЗ рд╕рдордп, рд╣рдо рдЗрд╕ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЗ рдорд╛рди рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реИрдВ: рдпрджрд┐ false
рд╡рд╣рд╛рдБ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЛ true
рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм рдПрдХ рдирдИ рд╡рд╕реНрддреБ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рдЬрд╛ рд░рд╣реА рд╣реИ, рддреЛ рдХреЛрдб рдореЗрдВ рдЧрд┐рд░ рдЬрд╛рдПрдЧрд╛, рдЬрдм рдкрд╣рд▓реА рд╡рд╕реНрддреБ рдмрдирд╛рддреЗ рд╕рдордп рд╣рдордиреЗ рд╕реНрдереИрддрд┐рдХ рдЪрд░ $hasInstance
true
рд▓рд┐рдЦрд╛ рдерд╛, рддреЛ if
'рд╢рд░реАрд░ рдореЗрдВ рд╣реИ, рдФрд░ рд╣рдо рдкрд╛рда рдХреЗ рд╕рд╛рде рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рддреНрд░реБрдЯрд┐ рдХрд╛ рдХрд╛рд░рдг рд╣реЛрдЧрд╛ Class is already instantiated
ред
рдореИрдЬрд┐рдХ рд╡рд┐рдзрд┐рдпреЛрдВ __wakeup()
__clone()
рдФрд░ __wakeup()
рд╣рдо рдПрдХ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ clone
рдСрдкрд░реЗрдЯрд░ рдФрд░ рдХреНрд░рдорд╛рдВрдХрди рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рднреА рдХрд╛рд░рдг рдмрдирддреЗ рд╣реИрдВред
рдпрджрд┐ рд╡рд╛рдВрдЫрд┐рдд рд╣реИ, рддреЛ рдЖрдк рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдмрдЬрд╛рдп рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рд╕рдХрддреЗ рд╣реИрдВред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХрдХреНрд╖рд╛ рдХрд╛ рд╕рд┐рд░реНрдл рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдЕрдм рддрдХ, рдореБрдЭреЗ рдкреИрдЯрд░реНрди рдХреЗ рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рддреЛрдбрд╝рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдХреЛрдИ рдРрд╕рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдЯрд┐рдкреНрдкрдгреА рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦреЗрдВ :)
рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!