📜 ⬆️ ⬇️

Making PHP strongly typed

This post is dedicated to lovers of typehints and strong typing, which PHP does not have by definition.


delving into PHP manuals recently, I came across a section on typehint , and accidentally climbed into comments, where I found a great (albeit heavy) solution for PHP5 how to make the language strongly typed. Under the cut solution.

 define('TYPEHINT_PCRE' ,'/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/'); class Typehint { private static $Typehints = array( 'boolean' => 'is_bool', 'integer' => 'is_int', 'float' => 'is_float', 'string' => 'is_string', 'resrouce' => 'is_resource' ); private function __constrct() {} public static function initializeHandler() { set_error_handler( 'Typehint::handleTypehint' ); return TRUE; } private static function getTypehintedArgument( $ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue ) { foreach ( $ThBackTrace as $ThTrace ) { // Match the function; Note we could do more defensive error checking. if ( isset($ThTrace[ 'function' ] ) && $ThTrace[ 'function' ] == $ThFunction) { $ThArgValue = $ThTrace[ 'args' ][ $ThArgIndex - 1 ]; return TRUE; } } return FALSE; } public static function handleTypehint( $ErrLevel, $ErrMessage ) { if ( $ErrLevel == E_RECOVERABLE_ERROR ) { if ( preg_match ( TYPEHINT_PCRE, $ErrMessage, $ErrMatches ) ) { list ( $ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType ) = $ErrMatches; if ( isset ( self::$Typehints [$ThHint] ) ) { $ThBacktrace = debug_backtrace(); $ThArgValue = NULL; if ( self::getTypehintedArgument ( $ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue ) ) { if ( call_user_func( self::$Typehints[ $ThHint ], $ThArgValue ) ) { return TRUE; } } } throw new Exception( $ErrMessage ); } } return FALSE; } } Typehint::initializeHandler(); 


And here are some tests:
 function teststring(string $string) { echo $string; } function testinteger(integer $integer) { echo $integer; } function testfloat(float $float) { echo $float; } try { teststring( 'string2' ); testinteger( 14 ); testfloat( 14.0 ); } catch ( Exception $e ) { echo $e->getMessage(); } 

')
original

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


All Articles