Пользовательские функции не проверяют типы принимаемых аргументов, для того чтобы это обойти я использую обработчик. Проблема в том, что в случае ошибки проверки возникает ошибка E_ERROR и ниже идуший не выполняется, приходится оборачивать каждую фунцию проверяющую типы аргументов в try catch , а мне хотелось бы чтобы выводилась ошибка E_NOTICE и код продолжал свое выполнение.
Посоветуйте что делать? Использовать set_exception_handler('exception_handler')? Может у кого-то есть в наработки в данном направлении? Буду благодарен за любую помощь!
Код | // Обработчик типов аргументов функций
final class TypeHint { static private $TypeHints = array( 'boolean' => 'is_bool', 'bool' => 'is_bool', 'integer' => 'self::is_int', 'int' => 'self::is_int', 'float' => 'self::is_float', 'double' => 'self::is_float', 'string' => 'is_string', 'resource' => 'is_resource', 'strict' => 'self::is_strict', // Имена классов\функций\аргуметов 'url_param' => 'self::is_url_param', // параметр ЧПУ ссылки 'file_name' => 'self::is_file_name', // Имя файла ); // Проверка на соотвествие типу integer \ int static private function is_int( $value ) { if( ( is_numeric($value) && is_string($value) && preg_match( '/^[-]{0,1}[0-9]+$/u', $value ) ) || is_int($value) ) { return TRUE; } else { return FALSE; }; } // Проверка на соотвествие типу float \ double static private function is_float( $value ) { if( ( is_numeric($value) && is_string($value) && preg_match( '/^[-]{0,1}[0-9]+\.[0-9]+$/u', $value ) ) || is_float($value) ) { return TRUE; } else { return FALSE; }; } // Проверка на соотвествие типу strict static private function is_strict( $value ) { if( is_string($value) && preg_match( '/^[a-z_\x7f-\xff]{2,}[a-z0-9_\x7f-\xff]*$/iu', $value ) ) { return TRUE; } else { return FALSE; }; } // Проверка на соотвествие типу url_param static private function is_url_param( $value ) { if( ( is_string($value) || is_int($value) ) && preg_match( '/^[a-z0-9_\x7f-\xff]+$/iu', $value ) ) { return TRUE; } else { return FALSE; }; } // Проверка на соотвествие типу file_name static private function is_file_name( $value ) { if( is_string($value) && preg_match( '/^[a-z0-9_\x7f-\xff]+\.[a-z0-9_\x7f-\xff]+$/iu', $value ) ) { return TRUE; } else { return FALSE; }; } // Создание объекта возможно только через метод initializeHandler private function __construct() {} // Инициализация обработчика static public function initializeHandler() { set_error_handler( 'TypeHint::handleTypeHint' ); return TRUE; } // Получение аргументов функции static private function getTypeHintedArgument( $ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue ) { foreach( $ThBackTrace as $ThTrace ) { if( isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction ) { $ThArgValue = $ThTrace['args'][$ThArgIndex - 1]; return TRUE; }; }; return FALSE; } // Обработчик static public function handleTypeHint( $ErrLevel, $ErrMessage, $ErrFile, $ErrLine ) { if( $ErrLevel == E_RECOVERABLE_ERROR ) { if( preg_match( '/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/u', $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; } else { throw new ErrorException( $ErrMessage, 0, $ErrLevel, $ErrFile, $ErrLine ); }; }; }; }; }; return FALSE; } }
// Инициализируем обработчик TypeHint::initializeHandler();
// Тест function test( strict $arg1, file_name $arg2, $arg3 = 1 ) { echo "<br>{$arg1} | {$arg2} | {$arg3}"; };
try{ test( 'func_2', array(1,2) ); } catch( ErrorException $e ) { echo "<br>".$e->getMessage(); }; try{ test( 10.1, 'str' ); } catch( ErrorException $e ) { echo "<br>".$e->getMessage(); }; try{ test( 'class_name', '02.jpg' ); } catch( ErrorException $e ) { echo "<br>".$e->getMessage(); };
|
|