3v4l.org

run code in 300+ PHP versions simultaneously
<?php trait CouldCheckMethods { private static array $couldBeCalled = []; public static function check(callable $method): void { if (!self::could($method)) { throw new BadMethodCallException( sprintf( '%s cannot be called. To call that method, method should have attribute `%s`', self::callableToString($method), static::class ) ); } } public static function could(callable $method): bool { $method = self::callableToString($method); if (!array_key_exists($method, self::$couldBeCalled)) { self::$couldBeCalled[$method] = self::checkMethod($method); } return self::$couldBeCalled[$method]; } private static function checkMethod(string $method): bool { try { if (PHP_MINOR_VERSION >= 3) { // This is because since 8.4 calling new RefMet() with 1 parametr is deprecated $reflection = ReflectionMethod::createFromMethodName($method); } else { // but createFromMethodName is not available before 8.3 $reflection = new ReflectionMethod($method); } } catch (ReflectionException) { return false; } return (bool) $reflection->getAttributes(static::class); } private static function callableToString(callable $method): string { if (is_array($method)) { return sprintf('%s::%s', is_object($method[0]) ? get_class($method[0]) : $method[0], $method[1]); } if ($method instanceof Closure) { return 'Closure'; } if (is_string($method)) { return $method; } if (is_object($method) && method_exists($method, '__invoke')) { return sprintf('%s::__invoke', $method::class); } throw new InvalidArgumentException('Unsupported callable type'); } } #[Attribute(Attribute::TARGET_METHOD)] class CouldCallStatically { use CouldCheckMethods; } #[Attribute(Attribute::TARGET_METHOD)] class CouldCallNonStatically { use CouldCheckMethods; } class MyClass { #[CouldCallNonStatically] #[CouldCallStatically] protected static function send(string $send) { var_dump([ 'We made it', $send ]); } #[CouldCallStatically] protected static function onlyWorkStatically(string $send) { var_dump([ 'Work only static', $send ]); } protected function stillProtected() { var_dump('This will failed, because of missing attribute'); } public function __call(string $name, array $arguments) { CouldCallNonStatically::check([$this, $name]); return $this::$name(...$arguments); } public static function __callStatic(string $name, array $arguments) { CouldCallStatically::check([self::class, $name]); return static::$name(...$arguments); } } $obj = new MyClass(); $obj->send('Non static call'); MyClass::send('Static call'); try { MyClass::onlyWorkStatically('Try only static call'); $obj->onlyWorkStatically('Oh that will failed'); } catch (Throwable $e) { var_dump($e->getMessage()); } try { $obj->stillProtected('Oh that will failed'); } catch (Throwable $e) { var_dump($e->getMessage()); } try { MyClass::stillProtected('Oh that will failed'); } catch (Throwable $e) { var_dump($e->getMessage()); }
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 42) Position 1 = 24
Branch analysis from position: 24
1 jumps found. (Code = 42) Position 1 = 34
Branch analysis from position: 34
1 jumps found. (Code = 42) Position 1 = 44
Branch analysis from position: 44
1 jumps found. (Code = 62) Position 1 = -2
Found catch point at position: 18
Branch analysis from position: 18
2 jumps found. (Code = 107) Position 1 = 19, Position 2 = -2
Branch analysis from position: 19
1 jumps found. (Code = 42) Position 1 = 34
Branch analysis from position: 34
Found catch point at position: 28
Branch analysis from position: 28
2 jumps found. (Code = 107) Position 1 = 29, Position 2 = -2
Branch analysis from position: 29
1 jumps found. (Code = 42) Position 1 = 44
Branch analysis from position: 44
Found catch point at position: 38
Branch analysis from position: 38
2 jumps found. (Code = 107) Position 1 = 39, Position 2 = -2
Branch analysis from position: 39
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/23bJY
function name:  (null)
number of ops:  45
compiled vars:  !0 = $obj, !1 = $e
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   66     0  E >   DECLARE_CLASS                                            'couldcallstatically'
   73     1        DECLARE_CLASS                                            'couldcallnonstatically'
  122     2        NEW                                              $2      'MyClass'
          3        DO_FCALL                                      0          
          4        ASSIGN                                                   !0, $2
  124     5        INIT_METHOD_CALL                                         !0, 'send'
          6        SEND_VAL_EX                                              'Non+static+call'
          7        DO_FCALL                                      0          
  125     8        INIT_STATIC_METHOD_CALL                                  'MyClass', 'send'
          9        SEND_VAL_EX                                              'Static+call'
         10        DO_FCALL                                      0          
  129    11        INIT_STATIC_METHOD_CALL                                  'MyClass', 'onlyWorkStatically'
         12        SEND_VAL_EX                                              'Try+only+static+call'
         13        DO_FCALL                                      0          
  130    14        INIT_METHOD_CALL                                         !0, 'onlyWorkStatically'
         15        SEND_VAL_EX                                              'Oh+that+will+failed'
         16        DO_FCALL                                      0          
         17      > JMP                                                      ->24
  131    18  E > > CATCH                                       last         'Throwable'
  132    19    >   INIT_FCALL                                               'var_dump'
         20        INIT_METHOD_CALL                                         !1, 'getMessage'
         21        DO_FCALL                                      0  $9      
         22        SEND_VAR                                                 $9
         23        DO_ICALL                                                 
  136    24    >   INIT_METHOD_CALL                                         !0, 'stillProtected'
         25        SEND_VAL_EX                                              'Oh+that+will+failed'
         26        DO_FCALL                                      0          
         27      > JMP                                                      ->34
  137    28  E > > CATCH                                       last         'Throwable'
  138    29    >   INIT_FCALL                                               'var_dump'
         30        INIT_METHOD_CALL                                         !1, 'getMessage'
         31        DO_FCALL                                      0  $12     
         32        SEND_VAR                                                 $12
         33        DO_ICALL                                                 
  142    34    >   INIT_STATIC_METHOD_CALL                                  'MyClass', 'stillProtected'
         35        SEND_VAL_EX                                              'Oh+that+will+failed'
         36        DO_FCALL                                      0          
         37      > JMP                                                      ->44
  143    38  E > > CATCH                                       last         'Throwable'
  144    39    >   INIT_FCALL                                               'var_dump'
         40        INIT_METHOD_CALL                                         !1, 'getMessage'
         41        DO_FCALL                                      0  $15     
         42        SEND_VAR                                                 $15
         43        DO_ICALL                                                 
  145    44    > > RETURN                                                   1

Class CouldCheckMethods:
Function check:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 6, Position 2 = 19
Branch analysis from position: 6
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 19
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/23bJY
function name:  check
number of ops:  20
compiled vars:  !0 = $method
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    7     0  E >   RECV                                             !0      
    9     1        INIT_STATIC_METHOD_CALL                                  'could'
          2        SEND_VAR_EX                                              !0
          3        DO_FCALL                                      0  $1      
          4        BOOL_NOT                                         ~2      $1
          5      > JMPZ                                                     ~2, ->19
   10     6    >   NEW                                              $3      'BadMethodCallException'
   11     7        INIT_FCALL                                               'sprintf'
   12     8        SEND_VAL                                                 '%25s+cannot+be+called.+To+call+that+method%2C+method+should+have+attribute+%60%25s%60'
   13     9        INIT_STATIC_METHOD_CALL                                  'callableToString'
         10        SEND_VAR_EX                                              !0
         11        DO_FCALL                                      0  $4      
         12        SEND_VAR                                                 $4
   14    13        FETCH_CLASS_NAME                                 ~5      
         14        SEND_VAL                                                 ~5
   11    15        DO_ICALL                                         $6      
   14    16        SEND_VAR_NO_REF_EX                                       $6
   10    17        DO_FCALL                                      0          
   14    18      > THROW                                         0          $3
   18    19    > > RETURN                                                   null

End of function check

Function could:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 9, Position 2 = 15
Branch analysis from position: 9
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 15
filename:       /in/23bJY
function name:  could
number of ops:  21
compiled vars:  !0 = $method
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   20     0  E >   RECV                                             !0      
   22     1        INIT_STATIC_METHOD_CALL                                  'callableToString'
          2        SEND_VAR_EX                                              !0
          3        DO_FCALL                                      0  $1      
          4        ASSIGN                                                   !0, $1
   23     5        FETCH_STATIC_PROP_R          unknown             ~3      'couldBeCalled'
          6        ARRAY_KEY_EXISTS                                 ~4      !0, ~3
          7        BOOL_NOT                                         ~5      ~4
          8      > JMPZ                                                     ~5, ->15
   24     9    >   INIT_STATIC_METHOD_CALL                                  'checkMethod'
         10        SEND_VAR_EX                                              !0
         11        DO_FCALL                                      0  $8      
         12        FETCH_STATIC_PROP_W          unknown             $6      'couldBeCalled'
         13        ASSIGN_DIM                                               $6, !0
         14        OP_DATA                                                  $8
   26    15    >   FETCH_STATIC_PROP_R          unknown             ~9      'couldBeCalled'
         16        FETCH_DIM_R                                      ~10     ~9, !0
         17        VERIFY_RETURN_TYPE                                       ~10
         18      > RETURN                                                   ~10
   27    19*       VERIFY_RETURN_TYPE                                       
         20*     > RETURN                                                   null

End of function could

Function checkmethod:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 2, Position 2 = 7
Branch analysis from position: 2
1 jumps found. (Code = 42) Position 1 = 11
Branch analysis from position: 11
1 jumps found. (Code = 42) Position 1 = 14
Branch analysis from position: 14
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 7
1 jumps found. (Code = 42) Position 1 = 14
Branch analysis from position: 14
Found catch point at position: 12
Branch analysis from position: 12
2 jumps found. (Code = 107) Position 1 = 13, Position 2 = -2
Branch analysis from position: 13
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/23bJY
function name:  checkMethod
number of ops:  23
compiled vars:  !0 = $method, !1 = $reflection
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   29     0  E >   RECV                                             !0      
   32     1      > JMPZ                                                     <true>, ->7
   33     2    >   INIT_STATIC_METHOD_CALL                                  'ReflectionMethod', 'createFromMethodName'
          3        SEND_VAR                                                 !0
          4        DO_FCALL                                      0  $2      
          5        ASSIGN                                                   !1, $2
   32     6      > JMP                                                      ->11
   35     7    >   NEW                                              $4      'ReflectionMethod'
          8        SEND_VAR_EX                                              !0
          9        DO_FCALL                                      0          
         10        ASSIGN                                                   !1, $4
         11    > > JMP                                                      ->14
   37    12  E > > CATCH                                       last         'ReflectionException'
   38    13    > > RETURN                                                   <false>
   40    14    >   INIT_METHOD_CALL                                         !1, 'getAttributes'
         15        FETCH_CLASS_NAME                                 ~7      
         16        SEND_VAL_EX                                              ~7
         17        DO_FCALL                                      0  $8      
         18        BOOL                                             ~9      $8
         19        VERIFY_RETURN_TYPE                                       ~9
         20      > RETURN                                                   ~9
   41    21*       VERIFY_RETURN_TYPE                                       
         22*     > RETURN                                                   null

End of function checkmethod

Function callabletostring:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 3, Position 2 = 20
Branch analysis from position: 3
2 jumps found. (Code = 43) Position 1 = 8, Position 2 = 12
Branch analysis from position: 8
1 jumps found. (Code = 42) Position 1 = 14
Branch analysis from position: 14
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 12
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 20
2 jumps found. (Code = 43) Position 1 = 22, Position 2 = 23
Branch analysis from position: 22
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 23
2 jumps found. (Code = 43) Position 1 = 25, Position 2 = 27
Branch analysis from position: 25
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 27
2 jumps found. (Code = 46) Position 1 = 29, Position 2 = 34
Branch analysis from position: 29
2 jumps found. (Code = 43) Position 1 = 35, Position 2 = 42
Branch analysis from position: 35
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 42
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 34
filename:       /in/23bJY
function name:  callableToString
number of ops:  48
compiled vars:  !0 = $method
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   43     0  E >   RECV                                             !0      
   45     1        TYPE_CHECK                                  128          !0
          2      > JMPZ                                                     ~1, ->20
   46     3    >   INIT_FCALL                                               'sprintf'
          4        SEND_VAL                                                 '%25s%3A%3A%25s'
          5        FETCH_DIM_R                                      ~2      !0, 0
          6        TYPE_CHECK                                  256          ~2
          7      > JMPZ                                                     ~3, ->12
          8    >   FETCH_DIM_R                                      ~4      !0, 0
          9        GET_CLASS                                        ~5      ~4
         10        QM_ASSIGN                                        ~6      ~5
         11      > JMP                                                      ->14
         12    >   FETCH_DIM_R                                      ~7      !0, 0
         13        QM_ASSIGN                                        ~6      ~7
         14    >   SEND_VAL                                                 ~6
         15        FETCH_DIM_R                                      ~8      !0, 1
         16        SEND_VAL                                                 ~8
         17        DO_ICALL                                         $9      
         18        VERIFY_RETURN_TYPE                                       $9
         19      > RETURN                                                   $9
   49    20    >   INSTANCEOF                                               !0, 'Closure'
         21      > JMPZ                                                     ~10, ->23
   50    22    > > RETURN                                                   'Closure'
   53    23    >   TYPE_CHECK                                   64          !0
         24      > JMPZ                                                     ~11, ->27
   54    25    >   VERIFY_RETURN_TYPE                                       !0
         26      > RETURN                                                   !0
   57    27    >   TYPE_CHECK                                  256  ~12     !0
         28      > JMPZ_EX                                          ~12     ~12, ->34
         29    >   INIT_FCALL                                               'method_exists'
         30        SEND_VAR                                                 !0
         31        SEND_VAL                                                 '__invoke'
         32        DO_ICALL                                         $13     
         33        BOOL                                             ~12     $13
         34    > > JMPZ                                                     ~12, ->42
   58    35    >   INIT_FCALL                                               'sprintf'
         36        SEND_VAL                                                 '%25s%3A%3A__invoke'
         37        FETCH_CLASS_NAME                                 ~14     !0
         38        SEND_VAL                                                 ~14
         39        DO_ICALL                                         $15     
         40        VERIFY_RETURN_TYPE                                       $15
         41      > RETURN                                                   $15
   60    42    >   NEW                                              $16     'InvalidArgumentException'
         43        SEND_VAL_EX                                              'Unsupported+callable+type'
         44        DO_FCALL                                      0          
         45      > THROW                                         0          $16
   61    46*       VERIFY_RETURN_TYPE                                       
         47*     > RETURN                                                   null

End of function callabletostring

End of class CouldCheckMethods.

Class CouldCallStatically: [no user functions]
Class CouldCallNonStatically: [no user functions]
Class MyClass:
Function send:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/23bJY
function name:  send
number of ops:  7
compiled vars:  !0 = $send
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   84     0  E >   RECV                                             !0      
   86     1        INIT_FCALL                                               'var_dump'
   87     2        INIT_ARRAY                                       ~1      'We+made+it'
   88     3        ADD_ARRAY_ELEMENT                                ~1      !0
          4        SEND_VAL                                                 ~1
   86     5        DO_ICALL                                                 
   90     6      > RETURN                                                   null

End of function send

Function onlyworkstatically:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/23bJY
function name:  onlyWorkStatically
number of ops:  7
compiled vars:  !0 = $send
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   93     0  E >   RECV                                             !0      
   95     1        INIT_FCALL                                               'var_dump'
   96     2        INIT_ARRAY                                       ~1      'Work+only+static'
   97     3        ADD_ARRAY_ELEMENT                                ~1      !0
          4        SEND_VAL                                                 ~1
   95     5        DO_ICALL                                                 
   99     6      > RETURN                                                   null

End of function onlyworkstatically

Function stillprotected:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/23bJY
function name:  stillProtected
number of ops:  4
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  103     0  E >   INIT_FCALL                                               'var_dump'
          1        SEND_VAL                                                 'This+will+failed%2C+because+of+missing+attribute'
          2        DO_ICALL                                                 
  104     3      > RETURN                                                   null

End of function stillprotected

Function __call:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/23bJY
function name:  __call
number of ops:  16
compiled vars:  !0 = $name, !1 = $arguments
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  107     0  E >   RECV                                             !0      
          1        RECV                                             !1      
  109     2        INIT_STATIC_METHOD_CALL                                  'CouldCallNonStatically', 'check'
          3        FETCH_THIS                                       ~2      
          4        INIT_ARRAY                                       ~3      ~2
          5        ADD_ARRAY_ELEMENT                                ~3      !0
          6        SEND_VAL_EX                                              ~3
          7        DO_FCALL                                      0          
  110     8        FETCH_THIS                                       ~5      
          9        FETCH_CLASS                                   0  $6      ~5
         10        INIT_STATIC_METHOD_CALL                                  $6, !0
         11        SEND_UNPACK                                              !1
         12        CHECK_UNDEF_ARGS                                         
         13        DO_FCALL                                      1  $7      
         14      > RETURN                                                   $7
  111    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/23bJY
function name:  __callStatic
number of ops:  13
compiled vars:  !0 = $name, !1 = $arguments
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
  114     0  E >   RECV                                             !0      
          1        RECV                                             !1      
  116     2        INIT_STATIC_METHOD_CALL                                  'CouldCallStatically', 'check'
          3        INIT_ARRAY                                       ~2      'MyClass'
          4        ADD_ARRAY_ELEMENT                                ~2      !0
          5        SEND_VAL_EX                                              ~2
          6        DO_FCALL                                      0          
  117     7        INIT_STATIC_METHOD_CALL                                  !0
          8        SEND_UNPACK                                              !1
          9        CHECK_UNDEF_ARGS                                         
         10        DO_FCALL                                      1  $4      
         11      > RETURN                                                   $4
  118    12*     > RETURN                                                   null

End of function __callstatic

End of class MyClass.

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
145.78 ms | 1033 KiB | 16 Q