3v4l.org

run code in 500+ PHP versions simultaneously
<?php #[Attribute] class Getter{} #[Attribute] class Setter{} class CallingInaccessibleUndeclaredMethod extends Exception{} class AccessingNonExistentProperty extends Exception{} class PassingInvalidNumberOfArguments extends Exception{} trait SetterGetter { private static array $listOfGettersAndSetters = []; private function getFieldNameFromMethodName(string $methodName): string { $fieldName = mb_substr($methodName, 3); $firstChar = mb_strtolower(mb_substr($fieldName, 0, 1)); $lastChars = mb_substr($fieldName, 1); $fieldName = $firstChar . $lastChars; return $fieldName; } private function getPropertyAccessMethods(string $methodName, object $object, string $fieldName): array { $methods = []; $property = new ReflectionProperty(get_class($object), $fieldName); $properties = $property->getAttributes(); foreach ($properties as $property) { $methodName = $property->getName(); if ($methodName === 'Setter') { $methods[] = 'set'; } elseif ($methodName === 'Getter') { $methods[] = 'get'; } } return $methods; } public function __call(string $name, array $arguments) { $prefix = mb_substr($name, 0, 3); if ($prefix !== 'get' && $prefix !== 'set') { throw new CallingInaccessibleUndeclaredMethod('Из необъявленных методов этого класса можно вызывать только геттер и сеттер.'); } $fieldName = $this->getFieldNameFromMethodName($name); if (!property_exists(get_class($this), $fieldName)) { throw new AccessingNonExistentProperty('В классе ' . get_class($object) . 'не существует свойства с именем' . $fieldName); } $fieldValue = $arguments[0] ?? null; if (isset(self::$listOfGettersAndSetters[$name]) && $prefix === 'get') { return self::$listOfGettersAndSetters[$name](); } elseif (isset(self::$listOfGettersAndSetters[$name]) && $prefix === 'set') { return self::$listOfGettersAndSetters[$name]($fieldValue); } else { $methods = $this->getPropertyAccessMethods($name, $this, $fieldName); if (!in_array($prefix, $methods)) { throw new CallingInaccessibleUndeclaredMethod('К этому полю нельзя обращаться через метод ' . $prefix); } if ($prefix === 'get') { if (count($arguments) !== 0) { throw new PassingInvalidNumberOfArguments('В геттер нельзя передавать аргументы.'); } self::$listOfGettersAndSetters[$name] = fn() => $this->$fieldName; return self::$listOfGettersAndSetters[$name](); } elseif ($prefix === 'set') { if (count($arguments) !== 1) { throw new PassingInvalidNumberOfArguments('В сеттер можно передавать только один аргумент.'); } self::$listOfGettersAndSetters[$name] = fn($fieldValue) => $this->$fieldName = $fieldValue; self::$listOfGettersAndSetters[$name]($fieldValue); } } } } class Test { use SetterGetter; #[Setter] #[Getter] private int $number; } $test = new Test(); $test->setNumber(5); echo $test->getNumber();
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/Jfpr9
function name:  (null)
number of ops:  11
compiled vars:  !0 = $test
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   87     0  E >   DECLARE_CLASS                                                'test'
   96     1        NEW                                                  $1      'Test'
          2        DO_FCALL                                          0          
          3        ASSIGN                                                       !0, $1
   97     4        INIT_METHOD_CALL                                             !0, 'setNumber'
          5        SEND_VAL_EX                                                  5
          6        DO_FCALL                                          0          
   98     7        INIT_METHOD_CALL                                             !0, 'getNumber'
          8        DO_FCALL                                          0  $5      
          9        ECHO                                                         $5
         10      > RETURN                                                       1

Class Getter: [no user functions]
Class Setter: [no user functions]
Class CallingInaccessibleUndeclaredMethod: [no user functions]
Class AccessingNonExistentProperty: [no user functions]
Class PassingInvalidNumberOfArguments: [no user functions]
Class SetterGetter:
Function getfieldnamefrommethodname:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/Jfpr9
function name:  getFieldNameFromMethodName
number of ops:  26
compiled vars:  !0 = $methodName, !1 = $fieldName, !2 = $firstChar, !3 = $lastChars
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   16     0  E >   RECV                                                 !0      
   18     1        INIT_FCALL                                                   'mb_substr'
          2        SEND_VAR                                                     !0
          3        SEND_VAL                                                     3
          4        DO_ICALL                                             $4      
          5        ASSIGN                                                       !1, $4
   19     6        INIT_FCALL                                                   'mb_strtolower'
          7        INIT_FCALL                                                   'mb_substr'
          8        SEND_VAR                                                     !1
          9        SEND_VAL                                                     0
         10        SEND_VAL                                                     1
         11        DO_ICALL                                             $6      
         12        SEND_VAR                                                     $6
         13        DO_ICALL                                             $7      
         14        ASSIGN                                                       !2, $7
   20    15        INIT_FCALL                                                   'mb_substr'
         16        SEND_VAR                                                     !1
         17        SEND_VAL                                                     1
         18        DO_ICALL                                             $9      
         19        ASSIGN                                                       !3, $9
   21    20        CONCAT                                               ~11     !2, !3
         21        ASSIGN                                                       !1, ~11
   22    22        VERIFY_RETURN_TYPE                                           !1
         23      > RETURN                                                       !1
   23    24*       VERIFY_RETURN_TYPE                                           
         25*     > RETURN                                                       null

End of function getfieldnamefrommethodname

Function getpropertyaccessmethods:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 14, Position 2 = 28
Branch analysis from position: 14
2 jumps found. (Code = 78) Position 1 = 15, Position 2 = 28
Branch analysis from position: 15
2 jumps found. (Code = 43) Position 1 = 20, Position 2 = 23
Branch analysis from position: 20
1 jumps found. (Code = 42) Position 1 = 27
Branch analysis from position: 27
1 jumps found. (Code = 42) Position 1 = 14
Branch analysis from position: 14
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 = 42) Position 1 = 14
Branch analysis from position: 14
Branch analysis from position: 27
Branch analysis from position: 28
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 28
filename:       /in/Jfpr9
function name:  getPropertyAccessMethods
number of ops:  33
compiled vars:  !0 = $methodName, !1 = $object, !2 = $fieldName, !3 = $methods, !4 = $property, !5 = $properties
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   25     0  E >   RECV                                                 !0      
          1        RECV                                                 !1      
          2        RECV                                                 !2      
   27     3        ASSIGN                                                       !3, <array>
   28     4        NEW                                                  $7      'ReflectionProperty'
          5        GET_CLASS                                            ~8      !1
          6        SEND_VAL_EX                                                  ~8
          7        SEND_VAR_EX                                                  !2
          8        DO_FCALL                                          0          
          9        ASSIGN                                                       !4, $7
   29    10        INIT_METHOD_CALL                                             !4, 'getAttributes'
         11        DO_FCALL                                          0  $11     
         12        ASSIGN                                                       !5, $11
   30    13      > FE_RESET_R                                           $13     !5, ->28
         14    > > FE_FETCH_R                                                   $13, !4, ->28
   31    15    >   INIT_METHOD_CALL                                             !4, 'getName'
         16        DO_FCALL                                          0  $14     
         17        ASSIGN                                                       !0, $14
   32    18        IS_IDENTICAL                                                 !0, 'Setter'
         19      > JMPZ                                                         ~16, ->23
   33    20    >   ASSIGN_DIM                                                   !3
         21        OP_DATA                                                      'set'
   32    22      > JMP                                                          ->27
   34    23    >   IS_IDENTICAL                                                 !0, 'Getter'
         24      > JMPZ                                                         ~18, ->27
   35    25    >   ASSIGN_DIM                                                   !3
         26        OP_DATA                                                      'get'
   30    27    > > JMP                                                          ->14
         28    >   FE_FREE                                                      $13
   38    29        VERIFY_RETURN_TYPE                                           !3
         30      > RETURN                                                       !3
   39    31*       VERIFY_RETURN_TYPE                                           
         32*     > RETURN                                                       null

End of function getpropertyaccessmethods

Function __call:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 46) Position 1 = 10, Position 2 = 12
Branch analysis from position: 10
2 jumps found. (Code = 43) Position 1 = 13, Position 2 = 17
Branch analysis from position: 13
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 17
2 jumps found. (Code = 43) Position 1 = 26, Position 2 = 34
Branch analysis from position: 26
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 34
2 jumps found. (Code = 46) Position 1 = 41, Position 2 = 43
Branch analysis from position: 41
2 jumps found. (Code = 43) Position 1 = 44, Position 2 = 50
Branch analysis from position: 44
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 50
2 jumps found. (Code = 46) Position 1 = 53, Position 2 = 55
Branch analysis from position: 53
2 jumps found. (Code = 43) Position 1 = 56, Position 2 = 63
Branch analysis from position: 56
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 63
2 jumps found. (Code = 43) Position 1 = 73, Position 2 = 78
Branch analysis from position: 73
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 78
2 jumps found. (Code = 43) Position 1 = 80, Position 2 = 98
Branch analysis from position: 80
2 jumps found. (Code = 43) Position 1 = 83, Position 2 = 87
Branch analysis from position: 83
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 87
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 98
2 jumps found. (Code = 43) Position 1 = 100, Position 2 = 117
Branch analysis from position: 100
2 jumps found. (Code = 43) Position 1 = 103, Position 2 = 107
Branch analysis from position: 103
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 107
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 117
Branch analysis from position: 55
Branch analysis from position: 43
Branch analysis from position: 12
filename:       /in/Jfpr9
function name:  __call
number of ops:  118
compiled vars:  !0 = $name, !1 = $arguments, !2 = $prefix, !3 = $fieldName, !4 = $object, !5 = $fieldValue, !6 = $methods
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   41     0  E >   RECV                                                 !0      
          1        RECV                                                 !1      
   43     2        INIT_FCALL                                                   'mb_substr'
          3        SEND_VAR                                                     !0
          4        SEND_VAL                                                     0
          5        SEND_VAL                                                     3
          6        DO_ICALL                                             $7      
          7        ASSIGN                                                       !2, $7
   45     8        IS_NOT_IDENTICAL                                     ~9      !2, 'get'
          9      > JMPZ_EX                                              ~9      ~9, ->12
         10    >   IS_NOT_IDENTICAL                                     ~10     !2, 'set'
         11        BOOL                                                 ~9      ~10
         12    > > JMPZ                                                         ~9, ->17
   46    13    >   NEW                                                  $11     'CallingInaccessibleUndeclaredMethod'
         14        SEND_VAL_EX                                                  '%D0%98%D0%B7+%D0%BD%D0%B5%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D1%85+%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2+%D1%8D%D1%82%D0%BE%D0%B3%D0%BE+%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0+%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE+%D0%B2%D1%8B%D0%B7%D1%8B%D0%B2%D0%B0%D1%82%D1%8C+%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE+%D0%B3%D0%B5%D1%82%D1%82%D0%B5%D1%80+%D0%B8+%D1%81%D0%B5%D1%82%D1%82%D0%B5%D1%80.'
         15        DO_FCALL                                          0          
         16      > THROW                                             0          $11
   49    17    >   INIT_METHOD_CALL                                             'getFieldNameFromMethodName'
         18        SEND_VAR_EX                                                  !0
         19        DO_FCALL                                          0  $13     
         20        ASSIGN                                                       !3, $13
   51    21        FETCH_THIS                                           ~15     
         22        GET_CLASS                                            ~16     ~15
         23        FRAMELESS_ICALL_2                property_exists      ~17     ~16, !3
         24        BOOL_NOT                                             ~18     ~17
         25      > JMPZ                                                         ~18, ->34
   52    26    >   NEW                                                  $19     'AccessingNonExistentProperty'
         27        GET_CLASS                                            ~20     !4
         28        CONCAT                                               ~21     '%D0%92+%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B5+', ~20
         29        CONCAT                                               ~22     ~21, '%D0%BD%D0%B5+%D1%81%D1%83%D1%89%D0%B5%D1%81%D1%82%D0%B2%D1%83%D0%B5%D1%82+%D1%81%D0%B2%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%B0+%D1%81+%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BC'
         30        CONCAT                                               ~23     ~22, !3
         31        SEND_VAL_EX                                                  ~23
         32        DO_FCALL                                          0          
         33      > THROW                                             0          $19
   55    34    >   FETCH_DIM_IS                                         ~25     !1, 0
         35        COALESCE                                             ~26     ~25
         36        QM_ASSIGN                                            ~26     null
         37        ASSIGN                                                       !5, ~26
   57    38        FETCH_STATIC_PROP_IS                                 ~28     'listOfGettersAndSetters'
         39        ISSET_ISEMPTY_DIM_OBJ                             0  ~29     ~28, !0
         40      > JMPZ_EX                                              ~29     ~29, ->43
         41    >   IS_IDENTICAL                                         ~30     !2, 'get'
         42        BOOL                                                 ~29     ~30
         43    > > JMPZ                                                         ~29, ->50
   58    44    >   FETCH_STATIC_PROP_R              unknown             ~31     'listOfGettersAndSetters'
         45        FETCH_DIM_R                                          ~32     ~31, !0
         46        INIT_DYNAMIC_CALL                                            ~32
         47        DO_FCALL                                          0  $33     
         48      > RETURN                                                       $33
   57    49*       JMP                                                          ->117
   59    50    >   FETCH_STATIC_PROP_IS                                 ~34     'listOfGettersAndSetters'
         51        ISSET_ISEMPTY_DIM_OBJ                             0  ~35     ~34, !0
         52      > JMPZ_EX                                              ~35     ~35, ->55
         53    >   IS_IDENTICAL                                         ~36     !2, 'set'
         54        BOOL                                                 ~35     ~36
         55    > > JMPZ                                                         ~35, ->63
   60    56    >   FETCH_STATIC_PROP_R              unknown             ~37     'listOfGettersAndSetters'
         57        FETCH_DIM_R                                          ~38     ~37, !0
         58        INIT_DYNAMIC_CALL                                            ~38
         59        SEND_VAR_EX                                                  !5
         60        DO_FCALL                                          0  $39     
         61      > RETURN                                                       $39
   59    62*       JMP                                                          ->117
   63    63    >   INIT_METHOD_CALL                                             'getPropertyAccessMethods'
         64        SEND_VAR_EX                                                  !0
         65        FETCH_THIS                                           $40     
         66        SEND_VAR_EX                                                  $40
         67        SEND_VAR_EX                                                  !3
         68        DO_FCALL                                          0  $41     
         69        ASSIGN                                                       !6, $41
   65    70        FRAMELESS_ICALL_2                in_array            ~43     !2, !6
         71        BOOL_NOT                                             ~44     ~43
         72      > JMPZ                                                         ~44, ->78
   66    73    >   NEW                                                  $45     'CallingInaccessibleUndeclaredMethod'
         74        CONCAT                                               ~46     '%D0%9A+%D1%8D%D1%82%D0%BE%D0%BC%D1%83+%D0%BF%D0%BE%D0%BB%D1%8E+%D0%BD%D0%B5%D0%BB%D1%8C%D0%B7%D1%8F+%D0%BE%D0%B1%D1%80%D0%B0%D1%89%D0%B0%D1%82%D1%8C%D1%81%D1%8F+%D1%87%D0%B5%D1%80%D0%B5%D0%B7+%D0%BC%D0%B5%D1%82%D0%BE%D0%B4+', !2
         75        SEND_VAL_EX                                                  ~46
         76        DO_FCALL                                          0          
         77      > THROW                                             0          $45
   69    78    >   IS_IDENTICAL                                                 !2, 'get'
         79      > JMPZ                                                         ~48, ->98
   70    80    >   COUNT                                                ~49     !1
         81        IS_NOT_IDENTICAL                                             ~49, 0
         82      > JMPZ                                                         ~50, ->87
   71    83    >   NEW                                                  $51     'PassingInvalidNumberOfArguments'
         84        SEND_VAL_EX                                                  '%D0%92+%D0%B3%D0%B5%D1%82%D1%82%D0%B5%D1%80+%D0%BD%D0%B5%D0%BB%D1%8C%D0%B7%D1%8F+%D0%BF%D0%B5%D1%80%D0%B5%D0%B4%D0%B0%D0%B2%D0%B0%D1%82%D1%8C+%D0%B0%D1%80%D0%B3%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B.'
         85        DO_FCALL                                          0          
         86      > THROW                                             0          $51
   73    87    >   DECLARE_LAMBDA_FUNCTION                              ~55     [0]
         88        BIND_LEXICAL                                                 ~55, !3
         89        FETCH_STATIC_PROP_W              unknown             $53     'listOfGettersAndSetters'
         90        ASSIGN_DIM                                                   $53, !0
         91        OP_DATA                                                      ~55
   74    92        FETCH_STATIC_PROP_R              unknown             ~56     'listOfGettersAndSetters'
         93        FETCH_DIM_R                                          ~57     ~56, !0
         94        INIT_DYNAMIC_CALL                                            ~57
         95        DO_FCALL                                          0  $58     
         96      > RETURN                                                       $58
   69    97*       JMP                                                          ->117
   75    98    >   IS_IDENTICAL                                                 !2, 'set'
         99      > JMPZ                                                         ~59, ->117
   76   100    >   COUNT                                                ~60     !1
        101        IS_NOT_IDENTICAL                                             ~60, 1
        102      > JMPZ                                                         ~61, ->107
   77   103    >   NEW                                                  $62     'PassingInvalidNumberOfArguments'
        104        SEND_VAL_EX                                                  '%D0%92+%D1%81%D0%B5%D1%82%D1%82%D0%B5%D1%80+%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE+%D0%BF%D0%B5%D1%80%D0%B5%D0%B4%D0%B0%D0%B2%D0%B0%D1%82%D1%8C+%D1%82%D0%BE%D0%BB%D1%8C%D0%BA%D0%BE+%D0%BE%D0%B4%D0%B8%D0%BD+%D0%B0%D1%80%D0%B3%D1%83%D0%BC%D0%B5%D0%BD%D1%82.'
        105        DO_FCALL                                          0          
        106      > THROW                                             0          $62
   80   107    >   DECLARE_LAMBDA_FUNCTION                              ~66     [1]
        108        BIND_LEXICAL                                                 ~66, !3
        109        FETCH_STATIC_PROP_W              unknown             $64     'listOfGettersAndSetters'
        110        ASSIGN_DIM                                                   $64, !0
        111        OP_DATA                                                      ~66
   81   112        FETCH_STATIC_PROP_R              unknown             ~67     'listOfGettersAndSetters'
        113        FETCH_DIM_R                                          ~68     ~67, !0
        114        INIT_DYNAMIC_CALL                                            ~68
        115        SEND_VAR_EX                                                  !5
        116        DO_FCALL                                          0          
   84   117    > > 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/Jfpr9
function name:  {closure:SetterGetter::__call():73}
number of ops:  4
compiled vars:  !0 = $fieldName
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   73     0  E >   BIND_STATIC                                                  !0
          1        FETCH_OBJ_R                                          ~1      !0
          2      > RETURN                                                       ~1
          3*     > 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/Jfpr9
function name:  {closure:SetterGetter::__call():80}
number of ops:  6
compiled vars:  !0 = $fieldValue, !1 = $fieldName
line      #* E I O op                               fetch          ext  return  operands
-----------------------------------------------------------------------------------------
   80     0  E >   RECV                                                 !0      
          1        BIND_STATIC                                                  !1
          2        ASSIGN_OBJ                                           ~2      !1
          3        OP_DATA                                                      !0
          4      > RETURN                                                       ~2
          5*     > RETURN                                                       null

End of Dynamic Function 1

End of function __call

End of class SetterGetter.

Class Test: [no user functions]

Generated using Vulcan Logic Dumper, using php 8.5.0


preferences:
157.85 ms | 1604 KiB | 15 Q