рдкрд╣рд▓реЗ рд▓реЗрдЦ рдореЗрдВ рд╕рд░реНрд╡реЗрдХреНрд╖рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рдореМрдЬреВрджрд╛ рдЖрдИрдбреАрдИ рдХреЛ рдЦреБрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдереЛрдбрд╝рд╛ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рд╢рд╛рдпрдж рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдкрд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА рдЧрдИ рдереАред
рдпрд╣ рдЕрднреА рддрдХ рдПрдХ рдФрд░ рд╣реИрд▓реЛ-рд╡рд░реНрд▓реНрдб-рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд▓реЗрдЦ рдирд╣реАрдВ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЬреЛ рд▓реЛрдЧ рдореВрд▓ рдмрд╛рддреЗрдВ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╡реЗ рдЖрд╕рд╛рдиреА
рд╕реЗ Habr├й рдкрд░ рдФрд░
рд░реВрд╕реА-рднрд╛рд╖рд╛ RTFG рджреЛрдиреЛрдВ
рдкрд░ рдмрд╣реБрдд рд╕рд╛рд░реА рд╕рд╛рдордЧреНрд░реА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдкреВрд░реНрд╡рд╛рдкреЗрдХреНрд╖рд╛рдПрдБ, рдмрд┐рдХреНрд░реА рдФрд░ рдиреБрдХрд╕рд╛рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд▓реЗрдЦред рдпрд╣ рдереЛрдбрд╝рд╛ PHP рд╣реЛрдЧрд╛, рдЬреНрдпрд╛рджрд╛рддрд░ рд╕реАред
рдЖрд╡рд╢реНрдпрдХ рд╢рд░реНрддреЗрдВ
рдпрджрд┐ рдЖрдк tl; dr рдкрдврд╝рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рддреБрд░рдВрдд
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдореИрдВ рджреВрд░ рд╕реЗ рд╢реБрд░реВ рдХрд░реВрдБрдЧрд╛рдореБрдЭреЗ рдкрд╛рдпрдерди рдкрд╕рдВрдж рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдореЗрдВ рдХреБрдЫ рдмрд┐рдВрджреБред рдФрд░ рдЬрдм рд╕реЗ рдореИрдВ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдкреАрдПрдЪрдкреА рдореЗрдВ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ, рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЙрдкрдХрд░рдг рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╣реЛред рд╣рд╛рд▓ рдХреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ PHP рдХрд╛рдлреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╣реА рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рдЕрднреА рднреА рдЧрд╛рдпрдм рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рд╕рдм рдХреБрдЫ рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рдореЗрдВ рд▓реЗрдирд╛ рд╣реЛрдЧрд╛ред рдкрд╣рд▓реЗ рдореБрдЦреНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдирд╛рдо рдФрд░ рдкрд╛рд╕рд┐рдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрдХреАрдХрд░рдг рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдерд╛ (
рдореЗрд░рд╛ рдПрдХ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ , рдЬреЛ рдЕрднреА рднреА рдПрдХ рд╡рд┐рдЪрд╛рд░ рдмрдирд╛рдиреЗ рдХреЗ рдЪрд░рдг рдореЗрдВ рд╣реИред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдореИрдВ рдЗрд╕рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦ рд╕рдХрддрд╛ рд╣реВрдВ ), рдЕрдм рдпрд╣рд╛рдВ рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рдФрд░ рдХреБрдЫ рдЕрдиреНрдп рд╡рд┐рдХрд╛рд╕ рд╣реИрдВред
рдлрдВрдХреНрд╢рди рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕ (рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдпрд╣рд╛рдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╕рдЬрд╛рд╡рдЯ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИрдВ) рдЖрдкрдХреЛ рддрд░реНрдХ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдкрд░рдд рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдХреЙрд▓ рдХреЛ рд▓рдкреЗрдЯрддреЗ рд╣реБрдП, рдмрд╛рдж рдХреЗ рдХрд╛рдо рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рдШреЛрд╖рдгрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд░реИрдкрд░ рдХреА рдПрдХ рд╕реВрдЪреА рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рдЕрдВрддрддрдГ рдХреБрдЫ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдореВрд▓ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмрджрд▓ рджреЗрдЧрд╛ред рдЕрдЬрдЧрд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдореЗрдВ рд╣рдореЗрдВ
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓рддреЗ рд╣реИрдВ:
@decomaker(argA, argB, ...) def func(arg1, arg2, ...): # ... # : func = decomaker(argA, argB, ...)(func)
PHP рдореЗрдВ рдРрд╕реА рдХреЛрдИ рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рдЗрд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рд▓реЗрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмрджрд▓рд╛рд╡ рдХреЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рд╣реИ (рдЬрдм рдмреБрд▓рд╛рдпрд╛ рдбреЗрдХреЛрд░реЗрдЯрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдЙрд╕ рдкрд░ рдФрд░ рдЕрдзрд┐рдХ)ред рдкрд╣рд▓рд╛ рд▓реЗрдЦ рдмрд┐рд▓реНрдХреБрд▓ рдЗрд╕реА рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╕рд┐рдВрдЯреИрдХреНрд╕-рдЪреЗрдХрд┐рдВрдЧ рдЖрдИрдбреАрдИ рдФрд░ рджреЛ рдХрдореЗрдВрдЯреЗрдЯрд░ рд╢рд┐рд╡рд┐рд░реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдиреЗ рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдХрд░ рджрд┐рдпрд╛ред рдирддреАрдЬрддрди, рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдЕрдзрд┐рдХ рдкреЛрд░реНрдЯреЗрдмрд▓ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдм рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рд╡рд░реНрдгрди рдПрдХрд▓-рдкрдВрдХреНрддрд┐ рдЯрд┐рдкреНрдкрдгреА # рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
- # рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдкрджрд╛рд╡рдирдд рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд╛рдорд╛рдиреНрдп //, / * рдФрд░ / ** рд╕реЗ рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдЧрд╛;
- рдПрдХ рдПрдХрд▓-рдкрдВрдХреНрддрд┐ рдЯрд┐рдкреНрдкрдгреА рдЧрд┐рд░рддреА рдирд╣реАрдВ рд╣реИ рдФрд░ рджреГрд╖реНрдЯрд┐ рдЦреЛрдирд╛ рдХрдард┐рди рд╣реИ;
рдЕрдЪрд╛рдирдХ, php 5.x рдореЗрдВ, рдбреЗрдХреЛрд░реЗрдЯрд░ рджрд┐рдЦрд╛рдИ рджреЗрдВрдЧреЗ рдФрд░ рдЕрдЬреАрдм рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╡рд╛рд▓реЗ рдЗрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рдПрдЧреАред
рд╡рд┐рд╡рд░рдг рдкреНрд░рд╛рд░реВрдк рдкрд░ рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдпрд╣ рддрдп рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рдЦреБрдж рдХреИрд╕реЗ рд▓рд╛рдЧреВ рд╣реЛрдВрдЧреЗред рдбреЗрдХреЛрд░реЗрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдореВрд▓ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдмрджрд▓рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ рдЕрдирд╛рдо рдХрд╛рд░реНрдп рдФрд░ рдХреНрд▓реЛрдЬрд░ рдХрд╛рдо рдЖрддреЗ рд╣реИрдВ:
рдХреБрдЫ php рдХреЛрдб <?php function decor($func) { echo "Decorator!\n"; return function () use($func) { return call_user_func_array($func, func_get_args()); }; } function a($v) { var_dump($v); } $b = decor('a'); $b(42);
PHP рдореЗрдВ, рдПрдХ рдЕрдкреНрд░рддреНрдпрдХреНрд╖ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдЬреЛ рдЗрд╕реЗ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╣реИ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдХреНрд░рд┐рдпрд╛ рд╣реИ, рдЗрд╕реЗ рджреВрд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдкрд░рд┐рдгрд╛рдо рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЫрд╡рд┐ рд╕реЗ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рд╣реИ:
<?php function decor($func) { return function(){} }
рдФрд░ рдореИрдВ рдЗрд╕реЗ
Zend рдХреЗ lexer рдХреЛ
рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд┐рдирд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рддрд╛рдХрд┐ рдЖрдкрдХреЛ PHP рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ рди рдкрдбрд╝реЗ (рдпрд╣
рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ - рдЗрд╕реЗ рд╕реНрдкрд░реНрд╢ рди рдХрд░реЗрдВ )ред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдпреЛрдЬрдирд╛ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рджреЛ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ:
- PHP рдХреЛрдбрд░ рдореЗрдВ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕реНрд░реЛрдд рдХреЛрдб рдмрджрд▓реЗрдВ;
- рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдУрдкрдХреЛрдб рдХреЛ рдмрджрд▓реЗрдВ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЛ рдореМрдЬреВрджрд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рджреВрд╕рд░рд╛ рд╡рд┐рдХрд▓реНрдк рдУрдкреЗрдХ рдХреИрд╢ рдФрд░ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝рд░ рдХреЗ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рдВрджрд┐рдЧреНрдз рд▓рдЧ рд░рд╣рд╛ рдерд╛ред рдФрд░ рдбреЗрдХреЛрд░реЗрдЯрд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ (# рдЯрд┐рдкреНрдкрдгреА рдХреЗ рдмрд┐рдирд╛) рдХрд╛ рдореВрд▓ рд╕рдВрд╕реНрдХрд░рдг рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛ рдЧрдпрд╛ рдерд╛ред
Zend рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рд░рд╛рдЬрд╕реНрд╡ рдХреЗ рджреЛ рд╕реНрд░реЛрдд рд╣реИрдВ:
- рдХреЛрдб рдХреЗ рд╕рд╛рде рдмрд╕ рдПрдХ рд▓рд╛рдЗрди (eval рдХрд╛ рдПрдирд╛рд▓реЙрдЧ): zend_eval_string [l] [_ ex] , рдЬреЛ рдЕрдВрддрддрдГ zend_compile_string рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдмрд▓рддрд╛ рд╣реИ ;
- рд╡рд┐рднрд┐рдиреНрди рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдПрдХ рдлрд╝рд╛рдЗрд▓ (рд╕реНрдЯрдбрд┐рди, рд╕реНрдЯреНрд░реАрдо, рдЖрджрд┐ред рд╕рднреА рд╡рд┐рдХрд▓реНрдк zend_stream_type рдЧрдгрди рдореЗрдВ рд╕реВрдЪреАрдмрджреНрдз рд╣реИрдВ)ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо zend_compile_file рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред
рджреЛрдиреЛрдВ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрдд рд╣реИрдВред рдорд╛рдирдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
zend_startup рдореЗрдВ
рд╢реБрд░реБрдЖрддреА рдмрд┐рдВрджреБрдУрдВ рдХреЛ
рджреЗрдЦрдХрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
- zend_compile_file рдХреЛ compile_file рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ;
- zend_compile_string - рд╕рдорд╛рди рд░реВрдк рд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╕рдВрдХрд▓рди_string рдореЗрдВред
рджреЛрдиреЛрдВ рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдпрд╛ рджреВрд╕рд░реЗ рд░реВрдк рдореЗрдВ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░
_zend_op_array рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд░реВрдк рдореЗрдВ
рдУрдкрдХреЛрдб рдХреА рдПрдХ рд╕рд░рдгреА рдЬрд╛рд░реА рдХрд░рддреЗ рд╣реИрдВред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдорд╛рдирддрд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЙрдирдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрд▓рдЧ рд╣реИред рдЗрд╕рд▓рд┐рдП рд╣рдо рджреЛрдиреЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░реЗрдВрдЧреЗред
Zend рдФрд░ PHP рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдВ рдРрд╕реЗ рдлрдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░реНрд╕ рдкрд░ рдкреНрд░рднрд╛рд╡ рд╕реНрдЯреНрд░реАрдо рдкрд░ рдбрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,
ZendAccelerator рдФрд░
Phar рдореЗрдВ рд╕рдорд╛рди zend_compile_file рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛
рдЬрд╛рддрд╛ рд╣реИ ред рдпрд╣ рддреГрддреАрдп-рдкрдХреНрд╖ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреА рдЧрдгрдирд╛ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред
рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рдПрдирд╛рд▓реЙрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдореВрд▓ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рд╕реВрдЪрдХ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╕рдм рдХреБрдЫ рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рд╣реИред
рдЖрдкрдХреЛ рдирд┐рдореНрди рдЬреИрд╕рд╛ рдХреБрдЫ рдорд┐рд▓рддрд╛ рд╣реИ PHP_MINIT_FUNCTION(decorators); PHP_MSHUTDOWN_FUNCTION(decorators); zend_module_entry decorators_module_entry = { // ... decorators_functions, PHP_MINIT(decorators), PHP_MSHUTDOWN(decorators), // ... }; zend_op_array *(*decorators_orig_zend_compile_string)(zval *source_string, char *filename TSRMLS_DC); zend_op_array *(*decorators_orig_zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC); zend_op_array* decorators_zend_compile_string(zval *source_string, char *filename TSRMLS_DC); zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(decorators) { decorators_orig_zend_compile_string = zend_compile_string; zend_compile_string = decorators_zend_compile_string; decorators_orig_zend_compile_file = zend_compile_file; zend_compile_file = decorators_zend_compile_file; return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(decorators) { zend_compile_string = decorators_orig_zend_compile_string; zend_compile_file = decorators_orig_zend_compile_file; return SUCCESS; } /* }}} */ zend_op_array* decorators_zend_compile_string(zval *source_string, char *filename TSRMLS_DC) /* {{{ */ { return decorators_orig_zend_compile_string(source_string, filename TSRMLS_CC); } /* }}} */ zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { return decorators_orig_zend_compile_file(file_handle, type TSRMLS_CC); } /* }}} */
рдЬрдм рдореЙрдбреНрдпреВрд▓ (рд╣рдорд╛рд░реЗ рд╡рд┐рд╕реНрддрд╛рд░) рдХреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рдХрд╛рдо рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░, рд╡реЗ рд╕рдм рдХреБрдЫ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдирд╣реАрдВ рднреВрд▓реЗред рд╕реАрдзреЗ рдмрджрд▓реЗ рд╣реБрдП рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ, рд╣рдо рдореВрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╣рддреЗ рд╣реИрдВред
рдореЙрдбреНрдпреВрд▓ рдЖрд░рдВрднреАрдХрд░рдг рдХреЗ рджреМрд░рд╛рди рд╕рдм рдХреБрдЫ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдХрд╛рдлреА рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред
рдФрд░ рдпрджрд┐ рдХрдВрдкрд╛рдЗрд▓_рд╕реНрдЯреНрд░рд┐рдВрдЧ (рдЗрдирдкреБрдЯ рд▓рд╛рдЗрди рдореЗрдВ рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП) рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рдХрдо рдпрд╛ рдЬреНрдпрд╛рджрд╛ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рддреЛ рдХрдВрдкрд╛рдЗрд▓_рдлрд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рдЗрддрдирд╛
рд░рд╕рд╛рддреНрдордХ рдирд╣реАрдВ рд╣реИ - рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реНрд░реЛрдд рдирд╣реАрдВ рд╣реИ, рдХреЗрд╡рд▓
zend_file_handle рдореЗрдВ рд╕реНрд░реЛрдд рдХрд╛ рд╡рд┐рд╡рд░рдг рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд┐рднрд┐рдиреНрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЦреЗрддреЛрдВ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рд╕реЗрдЯреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╕реНрд░реЛрдд рдХрд╛ рдкреНрд░рддреНрдпрдХреНрд╖ рдкрдврд╝рдирд╛ рдХрд╛рдлреА рджреВрд░ рджрдлрди рд╣реИ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) { // ... open_file_for_scanning(file_handle TSRMLS_CC) // ... } ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC) { // ... zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) // ... }
рдФрд░ рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд
zend_stream_fixup рд╣реИ , рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЗрдирдкреБрдЯ рдХреЗ рд╕рднреА рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдПрдХрдЬреБрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдПрдХ рд░реАрдб рдмрдлрд░ рдФрд░ рдЗрд╕рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рд╣рдо zend_stream_fixup рдФрд░ open_file_for_scanning рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЗрд╡рд▓ compile_file рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рд╣реИред
рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдЕрдкрдиреЗ рд╕рднреА рдЖрд╢реНрд░рд┐рддреЛрдВ рдХреЛ рдЦреБрдж рдХреА рдирдХрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рдЖрд╕рд╛рди рдмрдирд╛ рджреЗрдВрдЧреЗред рдпрджрд┐ рдЖрдк zend_stream_fixup рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдЕрдВрддрддрдГ рдПрдХ рд╣реА ZEND_HANDLE_MAPPED рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдлрд╝рд╛рдЗрд▓_рд╣реИрдВрдбрд▓-> рд╣реИрдВрдбрд▓ред ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдпрд╣ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА file_handle рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИ, рддреЛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдХреБрдЫ рднреА рдмрджрд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ рдФрд░ рд╕рдм рдХреБрдЫ рдЬреИрд╕рд╛ рд╣реИ рд╡реИрд╕рд╛ рд╣реА рд▓реМрдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдорд╛рди рдХреЗ рд╕рд╛рде ZEND_HANDLE_MAPPED рд╕реНрд╡рд░реВрдк рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрдВрдкрд╛рдЗрд▓_рдлрд╛рдЗрд▓ () zend_file_handle * file_handle рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ compile_file рдЗрд╕реЗ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд▓реЗрдЧрд╛ рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдерд╛ред рдФрд░ рд╣рдо рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ zend_stream_fixup (рдЬреЛ рдХрд┐ рдПрдХ Zend API рдлрд╝рдВрдХреНрд╢рди рд╣реИ, рди рдХрд┐ рдПрдХ рдмрджрд▓реА рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рд╕реВрдЪрдХ) рдХреЙрд▓ рдХрд░рдХреЗ compile_file рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдмрд╛рд░ред рдлрд┐рд░ open_file_for_scanning рдХреЗ рдЕрдВрджрд░ рдлрд┐рд░ рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ред
рдХреЛрд╢рд┐рд╢ zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) { char *buf; size_t size; if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) { return NULL; } // file_handle ZEND_HANDLE_MAPPED return decorators_orig_zend_compile_file(file_handle, type TSRMLS_CC); }
рд╣реБрд░реНрд░реЗ, рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, file_handle-> handle.stream.mmap.buf / len рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реНрд░реЛрдд рд╣реЛрддрд╛ рд╣реИ, рдЬрд╣рд╛рдБ рднреА PHP рдорд┐рд▓реЗрдЧреА: stdin, fd, http рд╕реНрдЯреНрд░реАрдо рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ ... рдпрд╣ рдХреЛрдб рдХреЗ рд╣рдорд╛рд░реЗ рд╕рдВрд╢реЛрдзрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рд╡рд╣рд╛рдВ рд░рдЦрдирд╛ рдФрд░ рдореВрд▓ zend_compile_file рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реИред
рдореИрдВ рдпрд╣ рдирд╣реАрдВ рд▓рд┐рдЦреВрдВрдЧрд╛ рдХрд┐ рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕_рдкрд░рдкреНрд░реЛрд╕реЗрд╕рд░ () рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд╕реНрдкрд╖реНрдЯ рд░рд╕реАрдж, рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЛ рдЗрд╕рдХрд╛ рдЯреНрд░рд╛рдВрд╕рдорд┐рд╢рди, рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рд╡рд╛рдкрд╕реАред рдиреАрдЪреЗ рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЗ рд╣реЛрдВрдЧреЗредрдпрд╣ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реА рд░рд╣рддрд╛ рд╣реИред
рдХрд┐рд╕реА рдПрдХрд▓ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЕрд╕рдорд╛рди рд╕реНрд░реЛрдд рдбреЗрдЯрд╛ рдкрд╛рд╕ рдХрд░рдирд╛ void preprocessor(zval *source_zv, zval *return_value TSRMLS_DC) { // source_zv return_value } /* {{{ DECORS_CALL_PREPROCESS */ #define DECORS_CALL_PREPROCESS(result_zv, buf, len) \ do { \ zval *source_zv; \ ALLOC_INIT_ZVAL(result_zv); \ ALLOC_INIT_ZVAL(source_zv); \ ZVAL_STRINGL(source_zv, (buf), (len), 1); \ preprocessor(source_zv, result_zv TSRMLS_CC); \ zval_dtor(source_zv); \ FREE_ZVAL(source_zv); \ } while (0); \ /* }}} */ /* {{{ proto string decorators_preprocessor(string $code) */ PHP_FUNCTION(decorators_preprocessor) { char *source; int source_len; zval *result; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &source, &source_len) == FAILURE) { return; } DECORS_CALL_PREPROCESS(result, source, source_len); // ... } /* }}} */ zend_op_array* decorators_zend_compile_string(zval *source_string, char *filename TSRMLS_DC) /* {{{ */ { zval *result; DECORS_CALL_PREPROCESS(result, Z_STRVAL_P(source_string), Z_STRLEN_P(source_string)); // ... } /* }}} */ zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { // ... zval *result; DECORS_CALL_PREPROCESS(result, file_handle->handle.stream.mmap.buf, file_handle->handle.stream.mmap.len); // ... } /* }}} */
рдвреВрдБрдвреЗрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рдХрд░реЗрдВ!
рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рдХрд╛рд░реНрдп рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕ рдХреЗ рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЛ рдЦреЛрдЬрдирд╛ рдФрд░ рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдбреЗрдХреЛрд░реЗрдЯрд░ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╕реНрд░реЛрдд рдкрд╛рда рдХреЗ рдЯреЛрдХрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИред рдкрд╣рд┐рдпрд╛ рдХреЛ рд╕реБрджреГрдврд╝ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рджреЗрд╢реА рдЬрд╝реЗрдВрдб рдХреЗ lex_scan рд▓реЗрдХреНрд╕рд┐рдХрд▓ рд╕реНрдХреИрдирд░ рдХрд╛
рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛,
рдЬрд┐рд╕рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг
token_get_all рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░
рдЯреЛрдХрди , token_get_all рдХреЗ рдЕрдВрджрд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
- рд╣рдо рдЙрд╕ рд╕реНрдХреИрдирд░ рдХреЗ рд╡рд░реНрддрдорд╛рди рд╡рд╛рддрд╛рд╡рд░рдг рдХреЛ рдмрдЪрд╛рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░рд╛ рдХреЛрдб рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
zend_lex_state original_lex_state;
zend_save_lexical_state (рдФрд░ original_lex_state TSRMLS_CC);
- рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕реЛрд░реНрд╕ рд▓рд╛рдЗрди рддреИрдпрд╛рд░ рдХрд░реЗрдВ:
zend_prepare_string_for_scanning (рдФрд░ source_z, "" TSRMLS_CC)
- рд╣рдордиреЗ рд▓реЗрдХреНрд╕рд░ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рд╣реИ (рд╕рднреА рд╡рд┐рдХрд▓реНрдк рдпрд╣рд╛рдВ рд╣реИрдВ ):
LANG_SCNG (yy_state) = yycST_IN_SCRIPTING;
Token_get_all рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА PHP рдХреЛрдб рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдПрдХ рдУрдкрдирд┐рдВрдЧ рдЯреИрдЧ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рддрджрдиреБрд╕рд╛рд░, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛ yycinitial рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди yycST_IN_SCRIPTING рд╣реИред
- рд▓реВрдк рдореЗрдВ рд╣рдореЗрдВ рд╕реНрд░реЛрдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рднреА рдЯреЛрдХрди рдорд┐рд▓рддреЗ рд╣реИрдВ:
zval token_zv;
int token_type;
рдЬрдмрдХрд┐ (token_type = lex_scan (& token_zv TSRMLS_CC)) {
// ...
}
token_type - рдЯреЛрдХрди рдкреНрд░рдХрд╛рд░:
- <256 - рдПрдХ рдЪрд░рд┐рддреНрд░ рд╡рд╛рд▓реЗ рдЯреЛрдХрди рдХрд╛ рдЪрд░рд┐рддреНрд░ рдХреЛрдб;
- > = 256 рд╕реНрдерд┐рд░ T_ * рдХрд╛ рдорд╛рди рд╣реИред Token_type рдХрд╛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╡рд┐рд╡рд░рдг PHP_FUNCTION (token_name) / get_token_type_name рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
token_zv рдореЗрдВ рдЯреЛрдХрди рдХрд╛ рдЕрд░реНрде рд╕рдорд╛рд╣рд┐рдд рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ, рдЖрдк zend_lex_state рд╕рдВрд░рдЪрдирд╛ рдХреЗ yy_text рдФрд░ yy_leng рдлрд╝реАрд▓реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╡рд░реНрддрдорд╛рди рдЯреЛрдХрди рдХреЗ рдкрд╣рд▓реЗ рдмрд╛рдЗрдЯ рдХрд╛ рдкрддрд╛ рдФрд░ рдЗрд╕рдХреА рд▓рдВрдмрд╛рдИ рдХреНрд░рдорд╢рдГ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВред рдЗрди рдХреНрд╖реЗрддреНрд░реЛрдВ рддрдХ рдкрд╣реБрдВрдЪ, рдЬреИрд╕реЗ Zend рдореЗрдВ, рдЗрд╕реА рдореИрдХреНрд░реЛрдЬрд╝ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИ:
#define zendtext LANG_SCNG (yy_text)
# рдбреЗрдлрд╝рд┐рди рдЬрд╝реЗрдВрдЧрд▓реЗрдВрдЧ LANG_SCNG (yy_leng)
рдЕрдм рд╣рдо рдЪрд╛рд░ * zendtext рдФрд░ рдЕрд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд int zendleng рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдореЗрдореЛрд░реА рд▓реАрдХ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдЯреЛрдХрди рдХрд╛ рдореВрд▓реНрдп рдХрднреА-рдХрднреА рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдореВрд▓ рдмрдлрд░ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдХрднреА-рдХрднреА рдЗрд╕рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред рдЬрд┐рд╕реЗ рдореБрдХреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд▓реЛрдЧ lex_scan () рдХреЛрдб рдХреЛ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдм token_get_all рд╕реЗ рддрд░реНрдХ рдХрд╛ рдЖрд╡рд╢реНрдпрдХ рдЯреБрдХрдбрд╝рд╛ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВред
- рд╣рдо рдЙрд╕ рд╕реНрдХреИрдирд░ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░рд╛ рдХреЛрдб рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
zend_restore_lexical_state (рдФрд░ original_lex_state TSRMLS_CC);
рдпрд╣ рд╕рдм рд╣реИ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рдПрдХ рд╢рд╛рдмреНрджрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╣реИред рд▓реЗрдХрд┐рди рдореИрдВ рдХреБрдЫ рдФрд░ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдореБрджреНрджреЛрдВ рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред
рдпрджрд┐ PHP рдкрд╛рд░реНрд╕рд┐рдВрдЧ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВ, рддреЛ рд╣реИрдВрдбрд▓рд░ рдПрдХ рддреНрд░реБрдЯрд┐ рдпрд╛ рдЕрдкрд╡рд╛рдж рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд╛рда рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рдФрд░ рд▓рд╛рдЗрди рдирдВрдмрд░
_zend_compiler_globals рд╕реНрдерд┐рддрд┐ рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рдВрдХрд▓рд┐рдд_рдлрд┐рд▓рдиреЗрдо рдлрд╝реАрд▓реНрдб рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЬрд┐рд╕реЗ zend_prepare_string_for_scanning () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ
zend_error рдХреЗ рдЕрдВрджрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (E_ * рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ; рдпрд╣ E_PARSE рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдореЗрдВ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред рд▓реЗрдХрд┐рди zend_error () рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд_filename рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рддрднреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм Zend рдПрдХ рд╕рдВрдХрд▓рди рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реЛ (zend_bool in_compilation; рд╕рднреА рдПрдХ рд╣реА _zend_compiler_globals рдореЗрдВ)ред рдпрджрд┐ рд╣рдо рд╕реНрд░реЛрдд рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╕реНрд╡рдпрдВ рд╕рдХреНрд░рд┐рдп рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рддреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо "рд╕рдВрдХрд▓рди" рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ:
zend_bool original_in_compilation = CG (in_compilation);
CG (in_compilation) = 1;
рдФрд░ рдЕрдВрдд рдореЗрдВ рд╣рдо рд╕рдм рдХреБрдЫ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрддреЗ рд╣реИрдВ:
CG (in_compilation) = original_in_compilation;
рдЕрдм, рдпрджрд┐ рд╣рдо zend_prepare_string_for_scanning рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдлрд╝рд╛рдЗрд▓рдирд╛рдо рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рдВрднрд╛рд╡рд┐рдд рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реАрдкреВрд░реНрдг рд╣реЛрдВрдЧреАред рдЖрдк рд╡рд░реНрддрдорд╛рди рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдХреЛ zend_get_compiled_filename () рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ, рд╣рд╛рд▓рд╛рдВрдХрд┐, NULL рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ php (рдпрджрд┐ NULL рдХреЛ zend_prepare_string_for_scanning рдХреЛ segfault рдореЗрдВ рдЧрд┐рд░ рдЬрд╛рдПрдЧрд╛)ред
рдпрд╣ рдбреЗрдХреЛрд░реЗрдЯрд░_рдкрд░рдкреНрд░реЛрд╕реЗрд╕рд░ рдФрд░ рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕_рдЬрд╝реЗрдВрдб_рдХрдореНрдкрд╛рдЗрд▓_рдлрд╛рдЗрд▓ рдореЗрдВ рд╕рд╣реА рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИ PHP_FUNCTION(decorators_preprocessor) { // ... char *prev_filename = zend_get_compiled_filename(TSRMLS_CC) ? zend_get_compiled_filename(TSRMLS_CC) : ""; zend_set_compiled_filename("-" TSRMLS_CC); DECORS_CALL_PREPROCESS(result, source, source_len); zend_set_compiled_filename(prev_filename TSRMLS_CC); // ... } zend_op_array* decorators_zend_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */ { // ... char *prev_filename = zend_get_compiled_filename(TSRMLS_CC) ? zend_get_compiled_filename(TSRMLS_CC) : ""; const char* filename = (file_handle->opened_path) ? file_handle->opened_path : file_handle->filename; zend_set_compiled_filename(filename TSRMLS_CC); zval *result; DECORS_CALL_PREPROCESS(result, file_handle->handle.stream.mmap.buf, file_handle->handle.stream.mmap.len); zend_set_compiled_filename(prev_filename TSRMLS_CC); // ... }
рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕_рдЬрд╝реЗрдВрдб_рдХрдореНрдкрд╛рдЗрд▓_рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ, рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рд╣рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬреНрдЮрд╛рдд рд╣реИред
рд╕реНрд░реЛрдд рдХреЛрдб рд╕рдВрд╢реЛрдзрди
рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдЪреАрдЬрд╝реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рдЗрд╕рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд░рд╣рддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдореА рдкрд╛рда рдореЗрдВ рдЪрдВрдХреНрд╕ (рдЯреЛрдХрди) рд╕реЗ рдмрдирд╛ рдкрд╛рда рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рд╕реА рдореЗрдВ рдЗрддрдирд╛ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ gluing рдХреЗ рд╕рд╛рде рд╕рдХреНрд░рд┐рдп рдХрд╛рд░реНрдп рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐,
/PHP/ext/standard/php_smart_str.h рдореЗрдВ рд╕реНрдорд╛рд░реНрдЯ рд▓рд╛рдЗрдиреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред
рдХрдо smart_str str = {0}; smart_str str2 = {0}; smart_str_appendc(&str, '!'); smart_str_appendl(&str, "hello", 5); smart_str_append(&str, &str2); smart_str_append_long(&str, 42);
рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдЯреЛрдХрди рдХреЗ рдЪрдХреНрд░ рдореЗрдВ, рдЯреЛрдХрди (рдЬрд╝реЗрдВрдбрдЯреЗрдХреНрд╕реНрдЯ, рдЬрд╝реЗрдВрдбреНрд▓реЗрдВрдЧ) рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдЧреЛрдВрдж рдХрд░реЗрдВ, рдЬрд╣рд╛рдВ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдмрджрд▓рдиреЗ / рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╕реАрдзреЗ рддреМрд░ рдкрд░ рдбреЗрдХреЛрд░реЗрдЯрд░, рдЖрдИрдПрдордПрдЪрдУ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрддрдирд╛ рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИред рд╕рдВрднрд╛рд╡рд┐рдд рджрд┐рд▓рдЪрд╕реНрдк рдмрд┐рдВрджреБ рд╕реЗ, рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдХрд┐ рдЯрд╛рдЗрдк T_COMMENT рдХрд╛ рдЯреЛрдХрди рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рдорд╛рди рд╣реИ: рдирд┐рдпрдорд┐рддрддрд╛ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ ^ ^ [[\ t] * @ '(рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд▓реВрдк рдХреЗ рд╕рд╛рде, рдмрд┐рдирд╛ regexp рдХреЗ) рдФрд░ рдкрддрд╛ @ @ рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ рд╣реИред
рдЕрдВрдд рдореЗрдВ рдереЛрдбрд╝рд╛ PHP
рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╕рдЬрд╛рдпрд╛ рдЧрдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╕реНрд░реЛрдд рдХреЛрдб рдереЛрдбрд╝рд╛ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ: рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╢рд░реАрд░ рдПрдХ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд▓рдкреЗрдЯрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рджреНрд╡рд╛рд░рд╛ рдирд┐рдХрдЯрддрдо рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╛рдиреА рдХреЛрдб рдХреЗ рд▓рд┐рдП
рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдирд┐рдореНрди рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛:
A, C, D, X рд╕реЗ рд╣рдорд╛рд░рд╛ рддрд╛рддреНрдкрд░реНрдп рд╣реИ рдордирдорд╛рдирд╛ рдХреЛрдб рдЬреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рдгрд╛рдо рдЗрд╕ рд╕реЗ рдЖрддреЗ рд╣реИрдВ:
- рдпрджрд┐ рд╕рдЬрд╛рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдлрд╝рдВрдХреНрд╢рди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рд╡рд╛рд▓реЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЕрдирд╛рдо рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд╕рдм рдХреБрдЫ рд╕рдорд╛рди рд╣реЛрдЧрд╛:
рдлрд╝рдВрдХреНрд╢рди рдлреВ ($ a, $ b = 42, $ c = рд╕рд░рдгреА (100, 500))
{...
=>
рдлрд╝рдВрдХреНрд╢рди рдлреВ ($ a, $ b = 42, $ c = рд╕рд░рдгреА (100, 500))
{return call_user_func_array (... (рдлрд╝рдВрдХреНрд╢рди ($ a, $ b = 42, $ c = array (100, 500)) {...
- рдпрджрд┐ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рдирд╛рдореЛрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реИрдВ, рддреЛ рддреНрд░реБрдЯрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╕рдордп рдХреЛрдб рдХреА рд▓рд╛рдЗрди рд╢рд░реАрд░ рдХреЛ рдЦреЛрд▓рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди '{' рдХреЗ рд╕рд╛рде рд╣реЛрдЧреАред рдЗрд╕реА рддрд░рд╣ рдбреЗрдХреЛрд░реЗрдЯрд░ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде - рд╡реЗ рд╢рд░реАрд░ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп '}' рдХреЗ рд╕рд╛рде рд▓рд╛рдЗрди рдореЗрдВ рд╣реЛрдВрдЧреЗ;
- рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕рдЬрд╛рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЪрд░ рдирд╛рдореЛрдВ рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рдирд┐рдпрдВрддреНрд░рдг рдкрдврд╝рддрд╛ / рд▓рд┐рдЦрддрд╛ рд╣реИ;
- рдХреНрдпреЛрдВрдХрд┐ func_get_args () рдХрд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рд╕рдЬрд╛рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд░рдирд╛ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
рдЦреИрд░, рдпрд╣ рдмрд╛рдд рд╣реИред рдпрджрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣рд╛рдБ рддрдХ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рдерд╛ред
рдореИрдВ рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ
github рдХрд╛ рд▓рд┐рдВрдХ рджреВрдВрдЧрд╛ред