📜 ⬆️ ⬇️

PHP Reflection Features

Everything written does not pretend to ideological fidelity, is not a working example of a controller, and is not recommended for mindless copying 1 to 1.

The idea of ​​writing the necessary parameters passed to the URL directly into the arguments of the function I overlooked in Symfony2. PHPdoc comments were also used to define routes.

For example, we want to see our controller like this:
class Controller { /** *   * @a /^[0-9]+$/i * @b /^[0-9a-z]+$/i */ function testAction ( $a, $b = 'something' ) { echo 'a: '.$a.', b: '.$b; } } 


')
If, despite the warnings, you want to use the example 1 in 1, you should know:
- Reflection API is slow
- Impossibility of obfuscation
- Non-obviousness and ideological curvature of architecture
- Possible difficulties with the support \ development in a team or third-party developers.


So, the task: if the variable “a” is not passed, or if “extra” variables are transferred, an error is generated, if the variable “b” is not specified, the default value is substituted. Both variables are checked using regular expressions written in PHPDoc.

As a result, the verification function was the following:
 function CheckURLValid ( $class, $method, $values_arr = array() ) { $class = new ReflectionClass( $class ); $method = $class->getMethod( $method ); $param = $method->getParameters(); $doc = $method->getDocComment(); // PHPdoc preg_match_all( '/@([a-z0-9_-]+)([^\n]+)/is', $doc, $arr ); $reg_arr = array_combine($arr[1], $arr[2]); //    $params_arr = array(); foreach ( $param as $p ) { $key = $p->getName(); $value = isset ( $values_arr[$key] ) ? $values_arr[$key] : false; $regular = isset ( $reg_arr[$key] ) ? trim($reg_arr[$key]) : false; $default = $p->isDefaultValueAvailable() ? $p->getDefaultValue() : NULL; //   -  if ( isset ( $values_arr[$key] ) ) { if ( $regular && !preg_match( $regular, $values_arr[$key] ) ) throw new Exception( ' "'.$key.'"  !' ); //       } elseif ( !$p->isOptional() ) throw new Exception( '    !' ); //     $params_arr[$key] = $value ? $value : $default; } //    if ( count(array_diff_key( $values_arr, $params_arr )) ) throw new Exception ( '  !' ); return $params_arr; } 


Example of use:
 try { $arr = CheckURLValid( 'Controller', 'testAction', $_GET ); call_user_func_array( array('Controller', 'testAction'), $arr ); } catch ( Exception $e ) { echo $e->getMessage(); } 

You can drive different variations of the type:
/test.php
/test.php?a=abc
/test.php?a=12
/test.php?a=12&b=another
/test.php?a=12&c=13

You can pick up a single file .

Source: https://habr.com/ru/post/139649/


All Articles