3v4l.org

run code in 500+ PHP versions simultaneously
<?php declare(strict_types = 1); namespace TradeoffDemo; class Foo { private string $secret = 'foo-secret'; public function hello(): string { return 'hello from ' . static::class; } } class SubFoo extends Foo { public function onlyInSubFoo(): string { return 'sub'; } } class NotFoo { } // Case 1: object/mixed bound into Foo scope is assumed to be Foo. function hydrate(object $object): mixed { return \Closure::bind(function () { if (!$this instanceof Foo) { return 'not a Foo: ' . get_class($this); } return $this->secret; }, $object, Foo::class)(); } // Case 2: a Foo bound into SubFoo scope is assumed to be SubFoo. function callSub(Foo $foo): mixed { return \Closure::bind(function () { if ($this instanceof SubFoo) { return $this->onlyInSubFoo(); } return 'plain Foo: ' . get_class($this); }, $foo, SubFoo::class)(); } // Case 3: the same, without a guard: PHPStan is silent, PHP fails at runtime. function readSecret(object $object): mixed { return \Closure::bind(fn () => $this->secret, $object, Foo::class)(); } function callSubUnguarded(Foo $foo): mixed { return \Closure::bind(fn () => $this->onlyInSubFoo(), $foo, SubFoo::class)(); } var_dump(hydrate(new Foo())); var_dump(hydrate(new NotFoo())); var_dump(callSub(new SubFoo())); var_dump(callSub(new Foo())); var_dump(readSecret(new NotFoo())); try { var_dump(callSubUnguarded(new Foo())); } catch (\Error $e) { echo get_class($e), ': ', $e->getMessage(), "\n"; }
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 42) Position 1 = 59
Branch analysis from position: 59
1 jumps found. (Code = 62) Position 1 = -2
Found catch point at position: 49
Branch analysis from position: 49
2 jumps found. (Code = 107) Position 1 = 50, Position 2 = -2
Branch analysis from position: 50
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  (null)
number of ops:  60
compiled vars:  !0 = $e
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   62     0  E >   INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cvar_dump'
          1        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Chydrate'
          2        NEW                                                  $1      'TradeoffDemo%5CFoo'
          3        DO_FCALL                                          0          
          4        SEND_VAR_NO_REF_EX                                           $1
          5        DO_FCALL                                          0  $3      
          6        SEND_VAR_NO_REF_EX                                           $3
          7        DO_FCALL                                          0          
   63     8        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cvar_dump'
          9        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Chydrate'
         10        NEW                                                  $5      'TradeoffDemo%5CNotFoo'
         11        DO_FCALL                                          0          
         12        SEND_VAR_NO_REF_EX                                           $5
         13        DO_FCALL                                          0  $7      
         14        SEND_VAR_NO_REF_EX                                           $7
         15        DO_FCALL                                          0          
   64    16        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cvar_dump'
         17        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5CcallSub'
         18        NEW                                                  $9      'TradeoffDemo%5CSubFoo'
         19        DO_FCALL                                          0          
         20        SEND_VAR_NO_REF_EX                                           $9
         21        DO_FCALL                                          0  $11     
         22        SEND_VAR_NO_REF_EX                                           $11
         23        DO_FCALL                                          0          
   65    24        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cvar_dump'
         25        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5CcallSub'
         26        NEW                                                  $13     'TradeoffDemo%5CFoo'
         27        DO_FCALL                                          0          
         28        SEND_VAR_NO_REF_EX                                           $13
         29        DO_FCALL                                          0  $15     
         30        SEND_VAR_NO_REF_EX                                           $15
         31        DO_FCALL                                          0          
   66    32        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cvar_dump'
         33        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5CreadSecret'
         34        NEW                                                  $17     'TradeoffDemo%5CNotFoo'
         35        DO_FCALL                                          0          
         36        SEND_VAR_NO_REF_EX                                           $17
         37        DO_FCALL                                          0  $19     
         38        SEND_VAR_NO_REF_EX                                           $19
         39        DO_FCALL                                          0          
   68    40        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cvar_dump'
         41        INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5CcallSubUnguarded'
         42        NEW                                                  $21     'TradeoffDemo%5CFoo'
         43        DO_FCALL                                          0          
         44        SEND_VAR_NO_REF_EX                                           $21
         45        DO_FCALL                                          0  $23     
         46        SEND_VAR_NO_REF_EX                                           $23
         47        DO_FCALL                                          0          
         48      > JMP                                                          ->59
   69    49  E > > CATCH                                           last         'Error'
   70    50    >   INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cget_class'
         51        SEND_VAR_EX                                                  !0
         52        DO_FCALL                                          0  $25     
         53        ECHO                                                         $25
         54        ECHO                                                         '%3A+'
         55        INIT_METHOD_CALL                                             !0, 'getMessage'
         56        DO_FCALL                                          0  $26     
         57        ECHO                                                         $26
         58        ECHO                                                         '%0A'
   71    59    > > RETURN                                                       1

Function tradeoffdemo%5Chydrate:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  TradeoffDemo\hydrate
number of ops:  12
compiled vars:  !0 = $object
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   28     0  E >   RECV                                                 !0      
   30     1        INIT_STATIC_METHOD_CALL                                      'Closure', 'bind'
          2        DECLARE_LAMBDA_FUNCTION                              ~1      [0]
   36     3        SEND_VAL                                                     ~1
          4        SEND_VAR                                                     !0
          5        SEND_VAL                                                     'TradeoffDemo%5CFoo'
   30     6        DO_FCALL                                          0  $2      
   36     7        INIT_DYNAMIC_CALL                                            $2
          8        DO_FCALL                                          0  $3      
          9      > RETURN                                                       $3
   37    10*       VERIFY_RETURN_TYPE                                           
         11*     > RETURN                                                       null


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 4, Position 2 = 10
Branch analysis from position: 4
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 10
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  {closure:TradeoffDemo\hydrate():30}
number of ops:  14
compiled vars:  none
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   31     0  E >   FETCH_THIS                                           ~0      
          1        INSTANCEOF                                           ~1      ~0, 'TradeoffDemo%5CFoo'
          2        BOOL_NOT                                             ~2      ~1
          3      > JMPZ                                                         ~2, ->10
   32     4    >   INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cget_class'
          5        FETCH_THIS                                           $3      
          6        SEND_VAR_EX                                                  $3
          7        DO_FCALL                                          0  $4      
          8        CONCAT                                               ~5      'not+a+Foo%3A+', $4
          9      > RETURN                                                       ~5
   35    10    >   FETCH_THIS                                           $6      
         11        FETCH_OBJ_R                                          ~7      $6, 'secret'
         12      > RETURN                                                       ~7
   36    13*     > RETURN                                                       null

End of Dynamic Function 0

End of function tradeoffdemo%5Chydrate

Function tradeoffdemo%5Ccallsub:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  TradeoffDemo\callSub
number of ops:  12
compiled vars:  !0 = $foo
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   40     0  E >   RECV                                                 !0      
   42     1        INIT_STATIC_METHOD_CALL                                      'Closure', 'bind'
          2        DECLARE_LAMBDA_FUNCTION                              ~1      [0]
   48     3        SEND_VAL                                                     ~1
          4        SEND_VAR                                                     !0
          5        SEND_VAL                                                     'TradeoffDemo%5CSubFoo'
   42     6        DO_FCALL                                          0  $2      
   48     7        INIT_DYNAMIC_CALL                                            $2
          8        DO_FCALL                                          0  $3      
          9      > RETURN                                                       $3
   49    10*       VERIFY_RETURN_TYPE                                           
         11*     > RETURN                                                       null


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 3, Position 2 = 7
Branch analysis from position: 3
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 7
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  {closure:TradeoffDemo\callSub():42}
number of ops:  14
compiled vars:  none
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   43     0  E >   FETCH_THIS                                           ~0      
          1        INSTANCEOF                                                   ~0, 'TradeoffDemo%5CSubFoo'
          2      > JMPZ                                                         ~1, ->7
   44     3    >   FETCH_THIS                                           $2      
          4        INIT_METHOD_CALL                                             $2, 'onlyInSubFoo'
          5        DO_FCALL                                          0  $3      
          6      > RETURN                                                       $3
   47     7    >   INIT_NS_FCALL_BY_NAME                                        'TradeoffDemo%5Cget_class'
          8        FETCH_THIS                                           $4      
          9        SEND_VAR_EX                                                  $4
         10        DO_FCALL                                          0  $5      
         11        CONCAT                                               ~6      'plain+Foo%3A+', $5
         12      > RETURN                                                       ~6
   48    13*     > RETURN                                                       null

End of Dynamic Function 0

End of function tradeoffdemo%5Ccallsub

Function tradeoffdemo%5Creadsecret:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  TradeoffDemo\readSecret
number of ops:  12
compiled vars:  !0 = $object
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   52     0  E >   RECV                                                 !0      
   54     1        INIT_STATIC_METHOD_CALL                                      'Closure', 'bind'
          2        DECLARE_LAMBDA_FUNCTION                              ~1      [0]
          3        SEND_VAL                                                     ~1
          4        SEND_VAR                                                     !0
          5        SEND_VAL                                                     'TradeoffDemo%5CFoo'
          6        DO_FCALL                                          0  $2      
          7        INIT_DYNAMIC_CALL                                            $2
          8        DO_FCALL                                          0  $3      
          9      > RETURN                                                       $3
   55    10*       VERIFY_RETURN_TYPE                                           
         11*     > RETURN                                                       null


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  {closure:TradeoffDemo\readSecret():54}
number of ops:  4
compiled vars:  none
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   54     0  E >   FETCH_THIS                                           $0      
          1        FETCH_OBJ_R                                          ~1      $0, 'secret'
          2      > RETURN                                                       ~1
          3*     > RETURN                                                       null

End of Dynamic Function 0

End of function tradeoffdemo%5Creadsecret

Function tradeoffdemo%5Ccallsubunguarded:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  TradeoffDemo\callSubUnguarded
number of ops:  12
compiled vars:  !0 = $foo
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   57     0  E >   RECV                                                 !0      
   59     1        INIT_STATIC_METHOD_CALL                                      'Closure', 'bind'
          2        DECLARE_LAMBDA_FUNCTION                              ~1      [0]
          3        SEND_VAL                                                     ~1
          4        SEND_VAR                                                     !0
          5        SEND_VAL                                                     'TradeoffDemo%5CSubFoo'
          6        DO_FCALL                                          0  $2      
          7        INIT_DYNAMIC_CALL                                            $2
          8        DO_FCALL                                          0  $3      
          9      > RETURN                                                       $3
   60    10*       VERIFY_RETURN_TYPE                                           
         11*     > RETURN                                                       null


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  {closure:TradeoffDemo\callSubUnguarded():59}
number of ops:  5
compiled vars:  none
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   59     0  E >   FETCH_THIS                                           $0      
          1        INIT_METHOD_CALL                                             $0, 'onlyInSubFoo'
          2        DO_FCALL                                          0  $1      
          3      > RETURN                                                       $1
          4*     > RETURN                                                       null

End of Dynamic Function 0

End of function tradeoffdemo%5Ccallsubunguarded

Class TradeoffDemo\Foo:
Function hello:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  hello
number of ops:  6
compiled vars:  none
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   11     0  E >   FETCH_CLASS_NAME                                     ~0      
          1        CONCAT                                               ~1      'hello+from+', ~0
          2        VERIFY_RETURN_TYPE                                           ~1
          3      > RETURN                                                       ~1
   12     4*       VERIFY_RETURN_TYPE                                           
          5*     > RETURN                                                       null

End of function hello

End of class TradeoffDemo\Foo.

Class TradeoffDemo\SubFoo:
Function onlyinsubfoo:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  onlyInSubFoo
number of ops:  3
compiled vars:  none
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   19     0  E > > RETURN                                                       'sub'
   20     1*       VERIFY_RETURN_TYPE                                           
          2*     > RETURN                                                       null

End of function onlyinsubfoo

Function hello:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/dhunm
function name:  hello
number of ops:  6
compiled vars:  none
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   11     0  E >   FETCH_CLASS_NAME                                     ~0      
          1        CONCAT                                               ~1      'hello+from+', ~0
          2        VERIFY_RETURN_TYPE                                           ~1
          3      > RETURN                                                       ~1
   12     4*       VERIFY_RETURN_TYPE                                           
          5*     > RETURN                                                       null

End of function hello

End of class TradeoffDemo\SubFoo.

Class TradeoffDemo\NotFoo: [no user functions]

Generated using Vulcan Logic Dumper, using php 8.5.0


preferences:
131.5 ms | 498 KiB | 15 Q