PHP.  . ,     
 


      .   ,    PHP   :   Zend Engine,       ,  ,    segmentation faults.    PHP-FPM     C-  FFI.  -  Copy-on-Write  Circuit Breaker   .

12   5     :    long-running ,   -  ,     $47 000   ,     .

 middle  senior PHP-,   ,    ,    .





PHP.  . ,     





 1.   




   PHP-  ,   :



PHP ,  HTTP-  . .



    ,    ,      PHP  ,   PHP.   ,        .

 ,       



 1: PHP   ,      .



PHP    -.  index.php   ,   AST (  )        Zend Engine.   -,    .  ,  OPCache  -    ,        .php-. PHP   Java HotSpot ( JIT  PHP 8+),   Bash.



 2: PHP    .



 .   .   (  PHP-FPM)       .  , :



    (MINIT),       .



    (RINIT),     HTTP-.



    (RSHUTDOWN),     ,     .



    PHP  C,     .    ,        long-running .



 3: PHP    HTTP.



SAPI (Server Application Programming Interface)   ,  Zend Engine      . HTTP-  Apache (mod_php), PHP-FPM (FastCGI)     SAPI.    PHP    (CLI SAPI),      (Embed SAPI)     .



        Enter     HTML.

1.1.  : SAPI, , 



  .

???????????????????????????????????

?  SAPI (PHP-FPM / CLI / Apache)  ?  ?    

???????????????????????????????????

?         Zend Engine             ?  ?   

??????????????????????????????????

? PDO?JSON?Mb  ?Curl?... ?   ?  ?  (extensions)

?    ?    ?    ?    ?    ?- ?

??????????????????????????????????



SAPI  ,   Zend Engine   .  API     ,   PHP;      .



Zend Engine   :   -   .



   :    array_map  PDO  ,   C.



  - (PHP-FPM)  FastCGI SAPI.   -,   .      ,     : accept  ?  ?  ?  .

1.2.    PHP-FPM (  C-)



 ,    C  PHP    ,       .

MINIT (Module Initialization)



      ().



  :



 , , ini- .



 ,        (,   shared memory).



   C  :

c



PHP_MINIT_FUNCTION(my_extension) {

REGISTER_INI_ENTRIES();

REGISTER_STRING_CONSTANT("MY_VERSION", "1.0", CONST_CS | CONST_PERSISTENT);

return SUCCESS;

}



 : MINIT   ,    . ,  ,     .    ,     MSHUTDOWN,   .

RINIT (Request Initialization)



   HTTP-.



   ,   :   ($_GET, $_POST, $_SERVER),     ,    persistent.



 : ,    RINIT,     RSHUTDOWN. PHP        ,       ,       ,   ,  .

 



 ,  (    OPCache),  .

RSHUTDOWN (Request Shutdown)



    (  )   .



 :



  ,    .



   ,    .



  .



 Persistent Database Connections    (  !).



MSHUTDOWN (Module Shutdown)



  ,    .



  ,   MINIT.     PHP-FPM ( SIGQUIT),     SIGKILL.

1.3.    (Shared-Nothing)



PHP  ,       . ,    ,   .   ,   .



:



     .



     : RSHUTDOWN  ,     unset().



 :        .



:



       PHP ( Redis, Memcached, APCu).



     ( OPCache  Preloading   ).



  :  ,  PHP    (Swoole, RoadRunner, ReactPHP),    RSHUTDOWN     .

1.4. PHP    -,    



         ==  .

  PHP-   



 1.   (Lexing)



      .    :

bash



php -r 'token_get_all("<?php echo 42;");'



  : T_OPEN_TAG, T_ECHO, T_LNUMBER, ;.  .



 2.   AST (Abstract Syntax Tree)



   ,    .  PHP 7     AST      .



  AST :

bash



php -r 'ast\parse_code("<?php echo 42;", $version=50);'



       : AST_STMT_LIST ? AST_ECHO ? 42.



 3.   



AST ,      Zend Engine:



ZEND_ECHO



ZEND_RETURN



  sum($a, $b) { return $a + $b; }   :



ZEND_RECV ( )



ZEND_ADD



ZEND_RETURN



 4.    



     ,    .  PHP 8.0  JIT-,          ,   .

1.5. OPCache:    13   



 PHP-FPM   ,     ,     index.php   . OPCache  ,   -    (shared memory).

  -



Memory-mapped     ,     PHP-FPM.



-  :    +  , :     .



       -,   interned strings,  , .



   PHP ,    OPCache  -  index.php.     ,    .    90%        .

Interned Strings



,    ( ,  ,  ),      .    "getUserById"   ,     shared memory,       .        (   memcmp).

Preloading (PHP 7.4+)



OPCache     PHP-     PHP-FPM       .     Java/.NET,          .



 php.ini  :

ini



opcache.preload=/app/preload.php



  preload.php  opcache_compile_file()   .    Symfony  Doctrine          .



 preloading':    preloaded-   PHP-FPM.          .

  



   PHP     .         ,   -,    JIT-.



PHP-FPM         (RINIT ? RSHUTDOWN).



PHP   ,    -,      JIT-.



OPCache     ,         .



Shared-nothing   ,         .



        PHP: ,   zval,   Copy-on-Write,    PHP 7      2-3   .




 2.    Zend Memory Manager




       PHP-,     .  ,  PHP   ,  $b = $a    ,       PHP 7,     1000,  3000     .



  .           =    .

2.1. Zval:   



    PHP    C,  zval (Zend Value). ,     , , ,    -   zval'  .



 zval  :

text



??????????????????????????????????????????????

?  value     ?  type      ?  refcount + info ?

?  (union)   ?  (byte)    ?  (bit-field)     ?

??????????????????????????????????????????????



value  union,    long, double,   ,   ,   - ()   .



type   : IS_LONG, IS_DOUBLE, IS_STRING, IS_ARRAY, IS_OBJECT  .



refcount    (Reference Counting).      zval.



 PHP 7      .  zval'  48  ( 64- ),   zval    .  ,  $a = 1        .          , .

2.2.   PHP 7:   



 PHP 7    .

-, zval   16 .



?



value  type :    ()     zval,   .



refcount   zval,        (  ).



-,         zval     .



    . $a = 42    16       ,      .



   ?     WordPress  Drupal     5070%. ,    1000  ,   3000   RAM.

2.3. ,   : zval  



   (, , ) zval       .    .



 PHP 7     zend_string:

text



zval (16 )          zend_string ( )

?????????????????      ?????????????????????????

?ptr? type?refc ? ???? ?ref?len?h  ? "hello"   ?

?   ?IS_STR?    ?      ?cnt? 5 ?   ?           ?

?????????????????      ?????????????????????????



refcnt (  zend_string)   zval',    .



len    ( ,  !).



h       -.



  .



   (zend_array  -)   (  zend_object).



 :    $b = $a  , zval'  (16 ),  zend_string  .  zval'         ,  refcnt    2.

2.4. Copy-on-Write:  PHP  ,    



, ,     PHP. PHP   ,     .

   :

php



$a = "Hello, World!";  // 1 zval, 1   , refcnt  = 1

$b = $a;               // 2 zval', 1   , refcnt  = 2

//     !



   $a  $b        .



  :

php



$b = "Goodbye!";       //     ,

// refcnt     1,

// $b    



 PHP 7    -     zval   (SEPARATE),   7-             zend_string.



Copy-on-Write  

CoW    .  :    refcnt > 1    -    .    PHP :

php



$a = [1, 2, 3];        //   refcnt = 1

$b = $a;               // refcnt  = 2

$b[] = 4;              //   (SEPARATE),

// $a  [1,2,3], $b    +  



,     :         refcnt  ,      .      (&$array)           .

2.5. Reference Counting  GC:   



      ,     . :

php



$a = new stdClass();

$b = new stdClass();

$a->ref = $b;

$b->ref = $a;

unset($a);

unset($b);

//     ! refcnt  = 1 (     )



      ,      .    ,   PHP 5.3      .

   (Cycle Collector)



PHP       .   :



   (zval'    )    .



   (  10 000 ),  .



   :     refcnt     .



   refcnt   0  ,       .    .



    .



   : gc_disable().              (      GC),      .       .

2.6.   Zend MM:   malloc



PHP     malloc    .      Zend Memory Manager, :



     ( mmap  malloc),  .



       zval', , .



         .



   :



:     , PHP-    .



:       .



  :  RSHUTDOWN PHP ,       ,      ,          .      (,   persistent,  ),   .



 



   ,  PHP        :



Zval  16- .    ,     .



PHP 7  zval    ,    .



Copy-on-Write     ;     .



Reference Counting  ,  zval   .



Cycle Collector   ,    .



Zend MM     PHP,      .



     ,     .     ,  Zend Engine   PHP-    zval'  ,   OPCache    .




 3. Zend Engine  OPCache




    ,  PHP     -.      -    .       : Zend Engine.  ,      ,   OPCache        .



   .  :     .     ,    PHP.

3.1.      



 PHP   index.php,    ,       echo.

text



  ?  ? AST ?  ? 



     ,        .

 1:   (Lexing)



:         .



 ()           .     :  + .



  :

php



<?php

$a = 42;

echo $a;



  :

text



T_OPEN_TAG      ("<?php\n")

T_VARIABLE      ("$a")

T_WHITESPACE    (" ")

=               ( )

T_LNUMBER       ("42")

;               ( )

T_ECHO          ("echo")

T_VARIABLE      ("$a")

;               ( )



    :

bash



php -r 'print_r(token_get_all(file_get_contents("test.php")));'



   :



   . $a = ;     (T_VARIABLE, '=', ';').    .



  .   .     ,  .



      (T_WHITESPACE, T_COMMENT).    .



  :     .    PHP    . OPCache     .

 2:  ,  AST



:        (AST).



       ,   .   $a = ;   :     '=',   ';'.



   AST    :

text



ZEND_AST_STMT_LIST

??? ZEND_AST_ASSIGN

?   ??? ZEND_AST_VAR ($a)

?   ??? ZEND_AST_ZVAL (42)

??? ZEND_AST_STMT_LIST

??? ZEND_AST_ECHO

??? ZEND_AST_VAR ($a)



 PHP 7    ,   AST.     .   AST :



   .



    (PHPStan, Psalm).



       .



   AST (  ast):

bash



php -r '

$code = "<?php \$a = 42; echo \$a;";

var_dump(ast\parse_code($code, 70));

'



    .  ,  LALR(1)-,   :  PHP -         .

 3:   



:  AST        .



  Zend Engine.   AST      .       ,   :



  (ZEND_ECHO, ZEND_ASSIGN, ZEND_ADD, ZEND_RETURN, ...)



 (  ,   zval')



  $a = 42; echo $a;     :

text



ZEND_ASSIGN      $a, 42

ZEND_ECHO        $a

ZEND_RETURN      null



      vld (Vulcan Logic Dumper)  phpdbg:

bash



php -d opcache.opt_debug_level=0x20000 -r '$a = 42; echo $a;' 2>&1 | grep -E "ZEND|opline"



 ,    OPCache:

bash



php -d opcache.opt_debug_level=0x10000 test.php



    :



 : , ,      .



  : 1 + 2      ZEND_ASSIGN $a, 3.   constant folding ( ).



  :  try/catch   .



     (op_array)   , ,        eval().

 4:    



:     .



  () Zend Engine    :

text



 ( ) {

  

  

   

}



      C (  ,  JIT  ). :



 ZEND_ECHO   ,        .



 ZEND_ASSIGN   ,       Copy-on-Write   .



ZEND_ADD   ,     zval.



 :   zval',      2.   ,    zval'.  zval'     .



 PHP 8.0    JIT- (Just-In-Time).      (,   )         x86/ARM,   .        (,  ),       -,      I/O    .

3.2. OPCache: ,    



        ,  .    Symfony  200+             .



OPCache    :      ()   .

  ?



OPCache     (shared memory)   PHP-:



  (op_array)     .



   ,    .



Interned strings      ( , , , )    -.



:   ,  .



   ?



  PHP  ,     -.  :



   .



 shared memory     .



  ,     (mtime)  .



    ,      .



        .



   stat.  -,         ,  stat  :

ini



opcache.validate_timestamps = 0



  OPCache      .   ,       PHP-FPM     opcache_reset().

Interned Strings:  ,   



,         "getUserById"   .          .  OPCache:



       interned strings.



 ,    ,    ,    .



      (O(1)  O(n)).



  .            .

3.3. Preloading: PHP  



OPCache    ,   :   PHP-FPM     .   ,   ,       .



Preloading,   PHP 7.4,   .



  :



 php.ini  preload-:



ini



opcache.preload = /app/preload.php

opcache.preload_user = www-data



       PHP-FPM -,  ,   .



   opcache_compile_file()     :



php



<?php

// preload.php

opcache_compile_file('/app/src/Entity/User.php');

opcache_compile_file('/app/src/Service/UserService.php');

// ...   Symfony/Doctrine



      OPCache      .



  :



     .



,  ,     (shared memory).



 3050%      Symfony-.



          .



 preloading:



  preloaded-   PHP-FPM.



  preloaded-   PHP-FPM  .



Preloaded-      class_alias      .



  : preload  ,    .



3.4.    

      ?



 ,  . OPCache   ,     .      .



    . 60 * 60 * 24   86400   .  : SECONDS_IN_A_DAY.



     .     ,    ,     . PSR-4      OPCache   .



Preloading  .  preload'     (  ,  ). Preload'     .



JIT    .   -  . JIT    ,    PHP   .

 



Zend Engine     ,  :

text



  ?  () ?  (AST) ?  () ?  ()



OPCache     ,               CPU.



Preloading  :          ,  PHP     .



  ,  PHP  .       ,     : ,  ,   strpos   false,   .




 4. ,   () 




  PHP  .     : , ,  .        ,  .  ,  strpos()   false,      0    .



          .

4.1. - : PHP  C



  C     ,    (\0).  strlen()  C  ,    \0.   : C-       .



PHP      . PHP- -.  :



     (  len  zend_string,      2).



      ,    .



strlen()  PHP         \0 .



:

php



$binary = "Hello\0World";

echo strlen($binary); // 11,  5!

echo $binary;         // "Hello"   ,   



   ?   PHP     . ,   $_FILES,   ,           .   PHP  C-,        .




  .


   .

   ,     (https://www.litres.ru/book/maksim-baytovich/php-pod-kapotom-arhitektura-pamyat-i-za-granu-koda-73916778/)  .

      Visa, MasterCard, Maestro,    ,   ,     ,  PayPal, WebMoney, ., QIWI ,       .


