3v4l.org

run code in 300+ PHP versions simultaneously
<?php class Collection { private $items; private static $macros = []; public static function macro($name, callable $macro) { static::$macros[$name] = Closure::fromCallable($macro); } public static function mixin($class) { foreach (get_class_methods($class) as $method) { static::macro($method, $class->$method()); } } public function __construct(array $items) { $this->items = $items; } public function map(callable $callback) { return new static(array_map($callback, $this->items)); } public function all() { return $this->items; } public function exampleClosure() { return function () { return $this->items; }; } public function __call($method, $args) { return static::$macros[$method]->bindTo($this, static::class)(...$args); } public static function __callStatic($method, $args) { return static::$macros[$method]->bindTo(null, static::class)(...$args); } } Collection::macro("flatMap", function (callable $callback) { $tmp = []; foreach ($this->items as $item) { $tmp = array_merge($tmp, $callback($item)); } return new static($tmp); }); $items = new Collection(["a", "b", "c"]); $items = $items->flatMap(function ($item) { return [$item, $item]; }); if ($items->all() === ["a", "a", "b", "b", "c", "c"]) { echo "it works"; } // This is the thing that is deprecated and causes a warning: // Here we're removing $this from a closure that isn't static // All non-static closures will have a $this in PHP 8.x when defined in a method try { var_dump( $items->exampleClosure()->bindTo(null)() ); } catch (\Throwable $e) { // We'll get an error about using $this is a non-object context // This will no longer be possible after PHP 7.4 var_dump($e); } // You can definitely still do this: class UnrelatedClass { private $items = ["foo", "bar"]; } var_dump( $items->exampleClosure()->bindTo(new UnrelatedClass, UnrelatedClass::class)() ); // The only thing that could cause problems is: // methods meant to be called statically in a mixin that were not defined with static: class SomeMixin { public function range() { return function ($start, $end) { return new static(range($start, $end)); }; } public function staticRange() { return static function ($start, $end) { return new static(range($start, $end)); }; } } Collection::mixin(new SomeMixin()); // This will error because: // 1. the above is not defined with static // 2. The closure is written inside a class var_dump(Collection::range(0, 10)); // The following will not because the closure was defined with static var_dump(Collection::staticRange(0, 10)); // Basically the change prevents the creation of methods and closures that can be used as instance and static methods at the same time by dynamically checking $this inside the function.
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 18, Position 2 = 19
Branch analysis from position: 18
1 jumps found. (Code = 42) Position 1 = 34
Branch analysis from position: 34
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 19
Found catch point at position: 30
Branch analysis from position: 30
2 jumps found. (Code = 107) Position 1 = 31, Position 2 = -2
Branch analysis from position: 31
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  (null)
number of ops:  67
compiled vars:  !0 = $items, !1 = $e
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   53     0  E >   INIT_STATIC_METHOD_CALL                                  'Collection', 'macro'
          1        SEND_VAL                                                 'flatMap'
          2        DECLARE_LAMBDA_FUNCTION                          ~2      [0]
   60     3        SEND_VAL                                                 ~2
   53     4        DO_FCALL                                      0          
   62     5        NEW                                              $4      'Collection'
          6        SEND_VAL_EX                                              <array>
          7        DO_FCALL                                      0          
          8        ASSIGN                                                   !0, $4
   63     9        INIT_METHOD_CALL                                         !0, 'flatMap'
         10        DECLARE_LAMBDA_FUNCTION                          ~7      [1]
   65    11        SEND_VAL_EX                                              ~7
   63    12        DO_FCALL                                      0  $8      
         13        ASSIGN                                                   !0, $8
   67    14        INIT_METHOD_CALL                                         !0, 'all'
         15        DO_FCALL                                      0  $10     
         16        IS_IDENTICAL                                             $10, <array>
         17      > JMPZ                                                     ~11, ->19
   68    18    >   ECHO                                                     'it+works'
   75    19    >   INIT_FCALL                                               'var_dump'
   76    20        INIT_METHOD_CALL                                         !0, 'exampleClosure'
         21        DO_FCALL                                      0  $12     
         22        INIT_METHOD_CALL                                         $12, 'bindTo'
         23        SEND_VAL_EX                                              null
         24        DO_FCALL                                      0  $13     
         25        INIT_DYNAMIC_CALL                                        $13
         26        DO_FCALL                                      0  $14     
         27        SEND_VAR                                                 $14
   75    28        DO_ICALL                                                 
   76    29      > JMP                                                      ->34
   78    30  E > > CATCH                                       last         'Throwable'
   81    31    >   INIT_FCALL                                               'var_dump'
         32        SEND_VAR                                                 !1
         33        DO_ICALL                                                 
   87    34    >   INIT_FCALL                                               'var_dump'
   88    35        INIT_METHOD_CALL                                         !0, 'exampleClosure'
         36        DO_FCALL                                      0  $17     
         37        INIT_METHOD_CALL                                         $17, 'bindTo'
         38        NEW                                              $18     'UnrelatedClass'
         39        DO_FCALL                                      0          
         40        SEND_VAR_NO_REF_EX                                       $18
         41        SEND_VAL_EX                                              'UnrelatedClass'
         42        DO_FCALL                                      0  $20     
         43        INIT_DYNAMIC_CALL                                        $20
         44        DO_FCALL                                      0  $21     
         45        SEND_VAR                                                 $21
   87    46        DO_ICALL                                                 
  110    47        INIT_STATIC_METHOD_CALL                                  'Collection', 'mixin'
         48        NEW                                              $23     'SomeMixin'
         49        DO_FCALL                                      0          
         50        SEND_VAR                                                 $23
         51        DO_FCALL                                      0          
  115    52        INIT_FCALL                                               'var_dump'
         53        INIT_STATIC_METHOD_CALL                                  'Collection', 'range'
         54        SEND_VAL_EX                                              0
         55        SEND_VAL_EX                                              10
         56        DO_FCALL                                      0  $26     
         57        SEND_VAR                                                 $26
         58        DO_ICALL                                                 
  118    59        INIT_FCALL                                               'var_dump'
         60        INIT_STATIC_METHOD_CALL                                  'Collection', 'staticRange'
         61        SEND_VAL_EX                                              0
         62        SEND_VAL_EX                                              10
         63        DO_FCALL                                      0  $28     
         64        SEND_VAR                                                 $28
         65        DO_ICALL                                                 
  120    66      > RETURN                                                   1


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 5, Position 2 = 15
Branch analysis from position: 5
2 jumps found. (Code = 78) Position 1 = 6, Position 2 = 15
Branch analysis from position: 6
1 jumps found. (Code = 42) Position 1 = 5
Branch analysis from position: 5
Branch analysis from position: 15
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
filename:       /in/3OKGT
function name:  {closure}
number of ops:  21
compiled vars:  !0 = $callback, !1 = $tmp, !2 = $item
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   53     0  E >   RECV                                             !0      
   54     1        ASSIGN                                                   !1, <array>
   55     2        FETCH_THIS                                       $4      
          3        FETCH_OBJ_R                                      ~5      $4, 'items'
          4      > FE_RESET_R                                       $6      ~5, ->15
          5    > > FE_FETCH_R                                               $6, !2, ->15
   56     6    >   INIT_FCALL                                               'array_merge'
          7        SEND_VAR                                                 !1
          8        INIT_DYNAMIC_CALL                                        !0
          9        SEND_VAR_EX                                              !2
         10        DO_FCALL                                      0  $7      
         11        SEND_VAR                                                 $7
         12        DO_ICALL                                         $8      
         13        ASSIGN                                                   !1, $8
   55    14      > JMP                                                      ->5
         15    >   FE_FREE                                                  $6
   59    16        NEW                          static              $10     
         17        SEND_VAR_EX                                              !1
         18        DO_FCALL                                      0          
         19      > RETURN                                                   $10
   60    20*     > RETURN                                                   null

End of Dynamic Function 0

Dynamic Function 1
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  {closure}
number of ops:  5
compiled vars:  !0 = $item
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   63     0  E >   RECV                                             !0      
   64     1        INIT_ARRAY                                       ~1      !0
          2        ADD_ARRAY_ELEMENT                                ~1      !0
          3      > RETURN                                                   ~1
   65     4*     > RETURN                                                   null

End of Dynamic Function 1

Class Collection:
Function macro:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  macro
number of ops:  9
compiled vars:  !0 = $name, !1 = $macro
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    8     0  E >   RECV                                             !0      
          1        RECV                                             !1      
   10     2        INIT_STATIC_METHOD_CALL                                  'Closure', 'fromCallable'
          3        SEND_VAR                                                 !1
          4        DO_FCALL                                      0  $4      
          5        FETCH_STATIC_PROP_W          global              $2      'macros'
          6        ASSIGN_DIM                                               $2, !0
          7        OP_DATA                                                  $4
   11     8      > RETURN                                                   null

End of function macro

Function mixin:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 5, Position 2 = 13
Branch analysis from position: 5
2 jumps found. (Code = 78) Position 1 = 6, Position 2 = 13
Branch analysis from position: 6
1 jumps found. (Code = 42) Position 1 = 5
Branch analysis from position: 5
Branch analysis from position: 13
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 13
filename:       /in/3OKGT
function name:  mixin
number of ops:  15
compiled vars:  !0 = $class, !1 = $method
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   13     0  E >   RECV                                             !0      
   15     1        INIT_FCALL                                               'get_class_methods'
          2        SEND_VAR                                                 !0
          3        DO_ICALL                                         $2      
          4      > FE_RESET_R                                       $3      $2, ->13
          5    > > FE_FETCH_R                                               $3, !1, ->13
   16     6    >   INIT_STATIC_METHOD_CALL                                  'macro'
          7        SEND_VAR_EX                                              !1
          8        INIT_METHOD_CALL                                         !0, !1
          9        DO_FCALL                                      0  $4      
         10        SEND_VAR_NO_REF_EX                                       $4
         11        DO_FCALL                                      0          
   15    12      > JMP                                                      ->5
         13    >   FE_FREE                                                  $3
   18    14      > RETURN                                                   null

End of function mixin

Function __construct:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  __construct
number of ops:  4
compiled vars:  !0 = $items
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   20     0  E >   RECV                                             !0      
   22     1        ASSIGN_OBJ                                               'items'
          2        OP_DATA                                                  !0
   23     3      > RETURN                                                   null

End of function __construct

Function map:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  map
number of ops:  11
compiled vars:  !0 = $callback
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   25     0  E >   RECV                                             !0      
   27     1        NEW                          static              $1      
          2        INIT_FCALL                                               'array_map'
          3        SEND_VAR                                                 !0
          4        FETCH_OBJ_R                                      ~2      'items'
          5        SEND_VAL                                                 ~2
          6        DO_ICALL                                         $3      
          7        SEND_VAR_NO_REF_EX                                       $3
          8        DO_FCALL                                      0          
          9      > RETURN                                                   $1
   28    10*     > RETURN                                                   null

End of function map

Function all:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  all
number of ops:  3
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   32     0  E >   FETCH_OBJ_R                                      ~0      'items'
          1      > RETURN                                                   ~0
   33     2*     > RETURN                                                   null

End of function all

Function exampleclosure:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  exampleClosure
number of ops:  3
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   37     0  E >   DECLARE_LAMBDA_FUNCTION                          ~0      [0]
   39     1      > RETURN                                                   ~0
   40     2*     > 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/3OKGT
function name:  {closure}
number of ops:  4
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   38     0  E >   FETCH_THIS                                       $0      
          1        FETCH_OBJ_R                                      ~1      $0, 'items'
          2      > RETURN                                                   ~1
   39     3*     > RETURN                                                   null

End of Dynamic Function 0

End of function exampleclosure

Function __call:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  __call
number of ops:  16
compiled vars:  !0 = $method, !1 = $args
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   42     0  E >   RECV                                             !0      
          1        RECV                                             !1      
   44     2        FETCH_STATIC_PROP_R          unknown             ~2      'macros'
          3        FETCH_DIM_R                                      ~3      ~2, !0
          4        INIT_METHOD_CALL                                         ~3, 'bindTo'
          5        FETCH_THIS                                       $4      
          6        SEND_VAR_EX                                              $4
          7        FETCH_CLASS_NAME                                 ~5      
          8        SEND_VAL_EX                                              ~5
          9        DO_FCALL                                      0  $6      
         10        INIT_DYNAMIC_CALL                                        $6
         11        SEND_UNPACK                                              !1
         12        CHECK_UNDEF_ARGS                                         
         13        DO_FCALL                                      1  $7      
         14      > RETURN                                                   $7
   45    15*     > RETURN                                                   null

End of function __call

Function __callstatic:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  __callStatic
number of ops:  15
compiled vars:  !0 = $method, !1 = $args
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   47     0  E >   RECV                                             !0      
          1        RECV                                             !1      
   49     2        FETCH_STATIC_PROP_R          unknown             ~2      'macros'
          3        FETCH_DIM_R                                      ~3      ~2, !0
          4        INIT_METHOD_CALL                                         ~3, 'bindTo'
          5        SEND_VAL_EX                                              null
          6        FETCH_CLASS_NAME                                 ~4      
          7        SEND_VAL_EX                                              ~4
          8        DO_FCALL                                      0  $5      
          9        INIT_DYNAMIC_CALL                                        $5
         10        SEND_UNPACK                                              !1
         11        CHECK_UNDEF_ARGS                                         
         12        DO_FCALL                                      1  $6      
         13      > RETURN                                                   $6
   50    14*     > RETURN                                                   null

End of function __callstatic

End of class Collection.

Class UnrelatedClass: [no user functions]
Class SomeMixin:
Function range:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  range
number of ops:  3
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   97     0  E >   DECLARE_LAMBDA_FUNCTION                          ~0      [0]
   99     1      > RETURN                                                   ~0
  100     2*     > 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/3OKGT
function name:  {closure}
number of ops:  11
compiled vars:  !0 = $start, !1 = $end
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   97     0  E >   RECV                                             !0      
          1        RECV                                             !1      
   98     2        NEW                          static              $2      
          3        INIT_FCALL                                               'range'
          4        SEND_VAR                                                 !0
          5        SEND_VAR                                                 !1
          6        DO_ICALL                                         $3      
          7        SEND_VAR_NO_REF_EX                                       $3
          8        DO_FCALL                                      0          
          9      > RETURN                                                   $2
   99    10*     > RETURN                                                   null

End of Dynamic Function 0

End of function range

Function staticrange:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/3OKGT
function name:  staticRange
number of ops:  3
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  104     0  E >   DECLARE_LAMBDA_FUNCTION                          ~0      [0]
  106     1      > RETURN                                                   ~0
  107     2*     > 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/3OKGT
function name:  {closure}
number of ops:  11
compiled vars:  !0 = $start, !1 = $end
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  104     0  E >   RECV                                             !0      
          1        RECV                                             !1      
  105     2        NEW                          static              $2      
          3        INIT_FCALL                                               'range'
          4        SEND_VAR                                                 !0
          5        SEND_VAR                                                 !1
          6        DO_ICALL                                         $3      
          7        SEND_VAR_NO_REF_EX                                       $3
          8        DO_FCALL                                      0          
          9      > RETURN                                                   $2
  106    10*     > RETURN                                                   null

End of Dynamic Function 0

End of function staticrange

End of class SomeMixin.

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
151.39 ms | 1036 KiB | 18 Q