3v4l.org

run code in 300+ PHP versions simultaneously
<?php function call_user_func_fixed() { // Not much point in writing all that logic out twice, just require that both fixer functions are present $args = func_get_args(); $callable = array_shift($args); return call_user_func_array_fixed($callable, $args); } function call_user_func_array_fixed($callable, $args) { $isStaticMethod = false; // Normalize the $callable and see if it looks like a static method if (is_object($callable) && $callable instanceof Closure) { $func = $callable; } else if (is_string($callable)) { $expr = '/^([a-z_\x7f-\xff][\w\x7f-\xff]*)::([a-z_\x7f-\xff][\w\x7f-\xff]*)$/i'; if (preg_match($expr, $callable, $matches)) { $func = array($matches[1], $matches[2]); $isStaticMethod = true; } else { $func = $callable; } } else if (is_array($callable) && isset($callable[0], $callable[1]) && count($callable) === 2) { if (is_object($callable[0])) { $func = $callable; } else if (is_string($callable[0])) { $func = $callable; $isStaticMethod = true; } } // If it's not a valid callable give up here if (!isset($callable) || (!$isStaticMethod && !is_callable($callable))) { trigger_error('call_user_func() expects parameter 1 to be a valid callback', E_USER_WARNING); return null; } // If it's not a static method use the regular mechanism if (!$isStaticMethod) { return call_user_func_array($func, $args); } // Get a reference to the target static method if possible try { if ($func[0] === 'self') { $backtrace = debug_backtrace(); // passing args here is fraught with complications for backwards compat :-( $key = $backtrace[1]['function'] === 'call_user_func_fixed' ? 2 : 1; if (empty($backtrace[$key]['class'])) { throw new Exception('Use of self in an invalid context'); } $class = new ReflectionClass($backtrace[$key]['class']); // I know this looks odd, but it's basically what self:: does $method = $class->getMethod($func[1])->getDeclaringClass()->getMethod($func[1]); if ($method->isPrivate() && (empty($backtrace[$key - 1]['class']) || $method->getDeclaringClass() !== $backtrace[$key - 1]['class'])) { var_dump($method->getDeclaringClass(), $backtrace[$key - 1]['class']); throw new Exception('Attempting to call private method in an invalid context'); } else if (method_exists($method, 'setAccessible')) { $method->setAccessible(true); // so we can call protected and allowable private methods } } else if ($func[0] === 'static' && function_exists('get_called_class')) { $class = new ReflectionClass(get_called_class()); $method = $class->getMethod($func[1]); } else { $class = new ReflectionClass($func[0]); $method = $class->getMethod($func[1]); } // Invoke the method with the passed arguments and return the result return $method->invokeArgs(null, $args); } catch (Exception $e) { trigger_error('call_user_func*() expects parameter 1 to be a valid callback: ' . $e->getMessage(), E_USER_WARNING); return null; } // Invoke the method with the passed arguments and return the result return $method->invokeArgs(null, $args); } class Car { public function run() { return call_user_func_fixed('self::getName'); // should call toyota } private static function getName() { return 'Car'; } } class Toyota extends Car { public static function getName() { return 'Toyota'; } } $car = new Car(); echo $car->run(); //Car instead of Toyota $toyota = new Toyota(); echo $toyota->run(); //Car instead of Toyota
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/BGGVp
function name:  (null)
number of ops:  13
compiled vars:  !0 = $car, !1 = $toyota
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  101     0  E >   NEW                                              $2      'Car'
          1        DO_FCALL                                      0          
          2        ASSIGN                                                   !0, $2
  102     3        INIT_METHOD_CALL                                         !0, 'run'
          4        DO_FCALL                                      0  $5      
          5        ECHO                                                     $5
  104     6        NEW                                              $6      'Toyota'
          7        DO_FCALL                                      0          
          8        ASSIGN                                                   !1, $6
  105     9        INIT_METHOD_CALL                                         !1, 'run'
         10        DO_FCALL                                      0  $9      
         11        ECHO                                                     $9
         12      > RETURN                                                   1

Function call_user_func_fixed:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/BGGVp
function name:  call_user_func_fixed
number of ops:  12
compiled vars:  !0 = $args, !1 = $callable
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    6     0  E >   FUNC_GET_ARGS                                    ~2      
          1        ASSIGN                                                   !0, ~2
    7     2        INIT_FCALL                                               'array_shift'
          3        SEND_REF                                                 !0
          4        DO_ICALL                                         $4      
          5        ASSIGN                                                   !1, $4
    9     6        INIT_FCALL_BY_NAME                                       'call_user_func_array_fixed'
          7        SEND_VAR_EX                                              !1
          8        SEND_VAR_EX                                              !0
          9        DO_FCALL                                      0  $6      
         10      > RETURN                                                   $6
   10    11*     > RETURN                                                   null

End of function call_user_func_fixed

Function call_user_func_array_fixed:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 46) Position 1 = 5, Position 2 = 7
Branch analysis from position: 5
2 jumps found. (Code = 43) Position 1 = 8, Position 2 = 10
Branch analysis from position: 8
1 jumps found. (Code = 42) Position 1 = 50
Branch analysis from position: 50
2 jumps found. (Code = 47) Position 1 = 53, Position 2 = 61
Branch analysis from position: 53
2 jumps found. (Code = 46) Position 1 = 55, Position 2 = 60
Branch analysis from position: 55
2 jumps found. (Code = 43) Position 1 = 62, Position 2 = 67
Branch analysis from position: 62
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 67
2 jumps found. (Code = 43) Position 1 = 69, Position 2 = 74
Branch analysis from position: 69
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 74
2 jumps found. (Code = 43) Position 1 = 77, Position 2 = 154
Branch analysis from position: 77
2 jumps found. (Code = 43) Position 1 = 84, Position 2 = 86
Branch analysis from position: 84
1 jumps found. (Code = 42) Position 1 = 87
Branch analysis from position: 87
2 jumps found. (Code = 43) Position 1 = 91, Position 2 = 95
Branch analysis from position: 91
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 95
2 jumps found. (Code = 46) Position 1 = 118, Position 2 = 130
Branch analysis from position: 118
2 jumps found. (Code = 47) Position 1 = 122, Position 2 = 129
Branch analysis from position: 122
2 jumps found. (Code = 43) Position 1 = 131, Position 2 = 145
Branch analysis from position: 131
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 145
2 jumps found. (Code = 43) Position 1 = 150, Position 2 = 153
Branch analysis from position: 150
1 jumps found. (Code = 42) Position 1 = 186
Branch analysis from position: 186
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 153
Branch analysis from position: 129
Branch analysis from position: 130
Branch analysis from position: 86
2 jumps found. (Code = 43) Position 1 = 91, Position 2 = 95
Branch analysis from position: 91
Branch analysis from position: 95
Branch analysis from position: 154
2 jumps found. (Code = 46) Position 1 = 157, Position 2 = 161
Branch analysis from position: 157
2 jumps found. (Code = 43) Position 1 = 162, Position 2 = 174
Branch analysis from position: 162
1 jumps found. (Code = 42) Position 1 = 186
Branch analysis from position: 186
Branch analysis from position: 174
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 161
Branch analysis from position: 60
Branch analysis from position: 61
Branch analysis from position: 10
2 jumps found. (Code = 43) Position 1 = 12, Position 2 = 28
Branch analysis from position: 12
2 jumps found. (Code = 43) Position 1 = 19, Position 2 = 26
Branch analysis from position: 19
1 jumps found. (Code = 42) Position 1 = 27
Branch analysis from position: 27
1 jumps found. (Code = 42) Position 1 = 50
Branch analysis from position: 50
Branch analysis from position: 26
1 jumps found. (Code = 42) Position 1 = 50
Branch analysis from position: 50
Branch analysis from position: 28
2 jumps found. (Code = 46) Position 1 = 30, Position 2 = 35
Branch analysis from position: 30
2 jumps found. (Code = 46) Position 1 = 32, Position 2 = 34
Branch analysis from position: 32
2 jumps found. (Code = 46) Position 1 = 36, Position 2 = 39
Branch analysis from position: 36
2 jumps found. (Code = 43) Position 1 = 40, Position 2 = 50
Branch analysis from position: 40
2 jumps found. (Code = 43) Position 1 = 43, Position 2 = 45
Branch analysis from position: 43
1 jumps found. (Code = 42) Position 1 = 50
Branch analysis from position: 50
Branch analysis from position: 45
2 jumps found. (Code = 43) Position 1 = 48, Position 2 = 50
Branch analysis from position: 48
2 jumps found. (Code = 47) Position 1 = 53, Position 2 = 61
Branch analysis from position: 53
Branch analysis from position: 61
Branch analysis from position: 50
Branch analysis from position: 50
Branch analysis from position: 39
Branch analysis from position: 34
Branch analysis from position: 35
Branch analysis from position: 7
Found catch point at position: 192
Branch analysis from position: 192
2 jumps found. (Code = 107) Position 1 = 193, Position 2 = -2
Branch analysis from position: 193
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/BGGVp
function name:  call_user_func_array_fixed
number of ops:  207
compiled vars:  !0 = $callable, !1 = $args, !2 = $isStaticMethod, !3 = $func, !4 = $expr, !5 = $matches, !6 = $backtrace, !7 = $key, !8 = $class, !9 = $method, !10 = $e
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   12     0  E >   RECV                                             !0      
          1        RECV                                             !1      
   14     2        ASSIGN                                                   !2, <false>
   17     3        TYPE_CHECK                                  256  ~12     !0
          4      > JMPZ_EX                                          ~12     ~12, ->7
          5    >   INSTANCEOF                                       ~13     !0, 'Closure'
          6        BOOL                                             ~12     ~13
          7    > > JMPZ                                                     ~12, ->10
   18     8    >   ASSIGN                                                   !3, !0
          9      > JMP                                                      ->50
   19    10    >   TYPE_CHECK                                   64          !0
         11      > JMPZ                                                     ~15, ->28
   20    12    >   ASSIGN                                                   !4, '%2F%5E%28%5Ba-z_%5Cx7f-%5Cxff%5D%5B%5Cw%5Cx7f-%5Cxff%5D%2A%29%3A%3A%28%5Ba-z_%5Cx7f-%5Cxff%5D%5B%5Cw%5Cx7f-%5Cxff%5D%2A%29%24%2Fi'
   21    13        INIT_FCALL                                               'preg_match'
         14        SEND_VAR                                                 !4
         15        SEND_VAR                                                 !0
         16        SEND_REF                                                 !5
         17        DO_ICALL                                         $17     
         18      > JMPZ                                                     $17, ->26
   22    19    >   FETCH_DIM_R                                      ~18     !5, 1
         20        INIT_ARRAY                                       ~19     ~18
         21        FETCH_DIM_R                                      ~20     !5, 2
         22        ADD_ARRAY_ELEMENT                                ~19     ~20
         23        ASSIGN                                                   !3, ~19
   23    24        ASSIGN                                                   !2, <true>
         25      > JMP                                                      ->27
   25    26    >   ASSIGN                                                   !3, !0
         27    > > JMP                                                      ->50
   27    28    >   TYPE_CHECK                                  128  ~24     !0
         29      > JMPZ_EX                                          ~24     ~24, ->35
         30    >   ISSET_ISEMPTY_DIM_OBJ                         0  ~25     !0, 0
         31      > JMPZ_EX                                          ~25     ~25, ->34
         32    >   ISSET_ISEMPTY_DIM_OBJ                         0  ~26     !0, 1
         33        BOOL                                             ~25     ~26
         34    >   BOOL                                             ~24     ~25
         35    > > JMPZ_EX                                          ~24     ~24, ->39
         36    >   COUNT                                            ~27     !0
         37        IS_IDENTICAL                                     ~28     ~27, 2
         38        BOOL                                             ~24     ~28
         39    > > JMPZ                                                     ~24, ->50
   28    40    >   FETCH_DIM_R                                      ~29     !0, 0
         41        TYPE_CHECK                                  256          ~29
         42      > JMPZ                                                     ~30, ->45
   29    43    >   ASSIGN                                                   !3, !0
         44      > JMP                                                      ->50
   30    45    >   FETCH_DIM_R                                      ~32     !0, 0
         46        TYPE_CHECK                                   64          ~32
         47      > JMPZ                                                     ~33, ->50
   31    48    >   ASSIGN                                                   !3, !0
   32    49        ASSIGN                                                   !2, <true>
   37    50    >   ISSET_ISEMPTY_CV                                 ~36     !0
         51        BOOL_NOT                                         ~37     ~36
         52      > JMPNZ_EX                                         ~37     ~37, ->61
         53    >   BOOL_NOT                                         ~38     !2
         54      > JMPZ_EX                                          ~38     ~38, ->60
         55    >   INIT_FCALL                                               'is_callable'
         56        SEND_VAR                                                 !0
         57        DO_ICALL                                         $39     
         58        BOOL_NOT                                         ~40     $39
         59        BOOL                                             ~38     ~40
         60    >   BOOL                                             ~37     ~38
         61    > > JMPZ                                                     ~37, ->67
   38    62    >   INIT_FCALL                                               'trigger_error'
         63        SEND_VAL                                                 'call_user_func%28%29+expects+parameter+1+to+be+a+valid+callback'
         64        SEND_VAL                                                 512
         65        DO_ICALL                                                 
   39    66      > RETURN                                                   null
   43    67    >   BOOL_NOT                                         ~42     !2
         68      > JMPZ                                                     ~42, ->74
   44    69    >   INIT_USER_CALL                                0          'call_user_func_array', !3
         70        SEND_ARRAY                                               !1
         71        CHECK_UNDEF_ARGS                                         
         72        DO_FCALL                                      0  $43     
         73      > RETURN                                                   $43
   49    74    >   FETCH_DIM_R                                      ~44     !3, 0
         75        IS_IDENTICAL                                             ~44, 'self'
         76      > JMPZ                                                     ~45, ->154
   50    77    >   INIT_FCALL                                               'debug_backtrace'
         78        DO_ICALL                                         $46     
         79        ASSIGN                                                   !6, $46
   51    80        FETCH_DIM_R                                      ~48     !6, 1
         81        FETCH_DIM_R                                      ~49     ~48, 'function'
         82        IS_IDENTICAL                                             ~49, 'call_user_func_fixed'
         83      > JMPZ                                                     ~50, ->86
         84    >   QM_ASSIGN                                        ~51     2
         85      > JMP                                                      ->87
         86    >   QM_ASSIGN                                        ~51     1
         87    >   ASSIGN                                                   !7, ~51
   53    88        FETCH_DIM_IS                                     ~53     !6, !7
         89        ISSET_ISEMPTY_DIM_OBJ                         1          ~53, 'class'
         90      > JMPZ                                                     ~54, ->95
   54    91    >   NEW                                              $55     'Exception'
         92        SEND_VAL_EX                                              'Use+of+self+in+an+invalid+context'
         93        DO_FCALL                                      0          
         94      > THROW                                         0          $55
   57    95    >   NEW                                              $57     'ReflectionClass'
         96        CHECK_FUNC_ARG                                           
         97        FETCH_DIM_FUNC_ARG                               $58     !6, !7
         98        FETCH_DIM_FUNC_ARG                               $59     $58, 'class'
         99        SEND_FUNC_ARG                                            $59
        100        DO_FCALL                                      0          
        101        ASSIGN                                                   !8, $57
   59   102        INIT_METHOD_CALL                                         !8, 'getMethod'
        103        CHECK_FUNC_ARG                                           
        104        FETCH_DIM_FUNC_ARG                               $62     !3, 1
        105        SEND_FUNC_ARG                                            $62
        106        DO_FCALL                                      0  $63     
        107        INIT_METHOD_CALL                                         $63, 'getDeclaringClass'
        108        DO_FCALL                                      0  $64     
        109        INIT_METHOD_CALL                                         $64, 'getMethod'
        110        CHECK_FUNC_ARG                                           
        111        FETCH_DIM_FUNC_ARG                               $65     !3, 1
        112        SEND_FUNC_ARG                                            $65
        113        DO_FCALL                                      0  $66     
        114        ASSIGN                                                   !9, $66
   61   115        INIT_METHOD_CALL                                         !9, 'isPrivate'
        116        DO_FCALL                                      0  $68     
        117      > JMPZ_EX                                          ~69     $68, ->130
        118    >   SUB                                              ~70     !7, 1
        119        FETCH_DIM_IS                                     ~71     !6, ~70
        120        ISSET_ISEMPTY_DIM_OBJ                         1  ~72     ~71, 'class'
        121      > JMPNZ_EX                                         ~72     ~72, ->129
        122    >   INIT_METHOD_CALL                                         !9, 'getDeclaringClass'
        123        DO_FCALL                                      0  $73     
        124        SUB                                              ~74     !7, 1
        125        FETCH_DIM_R                                      ~75     !6, ~74
        126        FETCH_DIM_R                                      ~76     ~75, 'class'
        127        IS_NOT_IDENTICAL                                 ~77     $73, ~76
        128        BOOL                                             ~72     ~77
        129    >   BOOL                                             ~69     ~72
        130    > > JMPZ                                                     ~69, ->145
   62   131    >   INIT_FCALL                                               'var_dump'
        132        INIT_METHOD_CALL                                         !9, 'getDeclaringClass'
        133        DO_FCALL                                      0  $78     
        134        SEND_VAR                                                 $78
        135        SUB                                              ~79     !7, 1
        136        FETCH_DIM_R                                      ~80     !6, ~79
        137        FETCH_DIM_R                                      ~81     ~80, 'class'
        138        SEND_VAL                                                 ~81
        139        DO_ICALL                                                 
   63   140        NEW                                              $83     'Exception'
        141        SEND_VAL_EX                                              'Attempting+to+call+private+method+in+an+invalid+context'
        142        DO_FCALL                                      0          
        143      > THROW                                         0          $83
        144*       JMP                                                      ->153
   64   145    >   INIT_FCALL                                               'method_exists'
        146        SEND_VAR                                                 !9
        147        SEND_VAL                                                 'setAccessible'
        148        DO_ICALL                                         $85     
        149      > JMPZ                                                     $85, ->153
   65   150    >   INIT_METHOD_CALL                                         !9, 'setAccessible'
        151        SEND_VAL_EX                                              <true>
        152        DO_FCALL                                      0          
        153    > > JMP                                                      ->186
   67   154    >   FETCH_DIM_R                                      ~87     !3, 0
        155        IS_IDENTICAL                                     ~88     ~87, 'static'
        156      > JMPZ_EX                                          ~88     ~88, ->161
        157    >   INIT_FCALL                                               'function_exists'
        158        SEND_VAL                                                 'get_called_class'
        159        DO_ICALL                                         $89     
        160        BOOL                                             ~88     $89
        161    > > JMPZ                                                     ~88, ->174
   68   162    >   NEW                                              $90     'ReflectionClass'
        163        GET_CALLED_CLASS                                 ~91     
        164        SEND_VAL_EX                                              ~91
        165        DO_FCALL                                      0          
        166        ASSIGN                                                   !8, $90
   69   167        INIT_METHOD_CALL                                         !8, 'getMethod'
        168        CHECK_FUNC_ARG                                           
        169        FETCH_DIM_FUNC_ARG                               $94     !3, 1
        170        SEND_FUNC_ARG                                            $94
        171        DO_FCALL                                      0  $95     
        172        ASSIGN                                                   !9, $95
        173      > JMP                                                      ->186
   71   174    >   NEW                                              $97     'ReflectionClass'
        175        CHECK_FUNC_ARG                                           
        176        FETCH_DIM_FUNC_ARG                               $98     !3, 0
        177        SEND_FUNC_ARG                                            $98
        178        DO_FCALL                                      0          
        179        ASSIGN                                                   !8, $97
   72   180        INIT_METHOD_CALL                                         !8, 'getMethod'
        181        CHECK_FUNC_ARG                                           
        182        FETCH_DIM_FUNC_ARG                               $101    !3, 1
        183        SEND_FUNC_ARG                                            $101
        184        DO_FCALL                                      0  $102    
        185        ASSIGN                                                   !9, $102
   76   186    >   INIT_METHOD_CALL                                         !9, 'invokeArgs'
        187        SEND_VAL_EX                                              null
        188        SEND_VAR_EX                                              !1
        189        DO_FCALL                                      0  $104    
        190      > RETURN                                                   $104
        191*       JMP                                                      ->201
   77   192  E > > CATCH                                       last         'Exception'
   78   193    >   INIT_FCALL                                               'trigger_error'
        194        INIT_METHOD_CALL                                         !10, 'getMessage'
        195        DO_FCALL                                      0  $105    
        196        CONCAT                                           ~106    'call_user_func%2A%28%29+expects+parameter+1+to+be+a+valid+callback%3A+', $105
        197        SEND_VAL                                                 ~106
        198        SEND_VAL                                                 512
        199        DO_ICALL                                                 
   79   200      > RETURN                                                   null
   83   201*       INIT_METHOD_CALL                                         !9, 'invokeArgs'
        202*       SEND_VAL_EX                                              null
        203*       SEND_VAR_EX                                              !1
        204*       DO_FCALL                                      0  $108    
        205*       RETURN                                                   $108
   84   206*     > RETURN                                                   null

End of function call_user_func_array_fixed

Class Car:
Function run:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/BGGVp
function name:  run
number of ops:  5
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   88     0  E >   INIT_FCALL                                               'call_user_func_fixed'
          1        SEND_VAL                                                 'self%3A%3AgetName'
          2        DO_FCALL                                      0  $0      
          3      > RETURN                                                   $0
   89     4*     > RETURN                                                   null

End of function run

Function getname:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/BGGVp
function name:  getName
number of ops:  2
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   91     0  E > > RETURN                                                   'Car'
   92     1*     > RETURN                                                   null

End of function getname

End of class Car.

Class Toyota:
Function getname:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/BGGVp
function name:  getName
number of ops:  2
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   97     0  E > > RETURN                                                   'Toyota'
   98     1*     > RETURN                                                   null

End of function getname

Function run:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/BGGVp
function name:  run
number of ops:  5
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   88     0  E >   INIT_FCALL                                               'call_user_func_fixed'
          1        SEND_VAL                                                 'self%3A%3AgetName'
          2        DO_FCALL                                      0  $0      
          3      > RETURN                                                   $0
   89     4*     > RETURN                                                   null

End of function run

End of class Toyota.

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
189.3 ms | 1414 KiB | 31 Q