PHP Classes

File: Xyndravandria/Erozaver/Erozaver.php

Recommend this page to a friend!
  Classes of Mauro Di Girolamo   Xyndravandria Erozaver   Xyndravandria/Erozaver/Erozaver.php   Download  
File: Xyndravandria/Erozaver/Erozaver.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Xyndravandria Erozaver
Validate function parameters with type hinting
Author: By
Last change: Alpha 0.0.0
Date: 10 years ago
Size: 13,169 bytes
 

Contents

Class file image Download
<?php /* ============================================================================================================================================= | This file is part of a project released under the terms of the Xyndravandria PHP License (XyndravandriaPHPLicense.txt). | | | | You should be given a copy of the Xyndravandria PHP License (XyndravandriaPHPLicense.txt) within the same directory as the README.md; | | if not, you can get a copy at http://Xyndravandria.ohost.de/XyndravandriaPHPLicense.txt . | | | | The copyright (c) of this project is owned by Mauro Di Girolamo <maurodigirolamo@.web.de>. | ============================================================================================================================================| Xyndravandria Erozaver ---------------------- Alpha 0.0.0 Xyndravandria is the name of a collection of projects designed and developed by Mauro Di Girolamo (maurodigirolamo@web.de); he is therefore the copyright (c) owner of Xyndravandria itself and all of its projects. Xyndravandria Erozaver is released under the terms of the Xyndravandria PHP License (XyndravandriaPHPLicense.txt). You should be given a copy of the Xyndravandria PHP License (XyndravandriaPHPLicense.txt) within the same directory as the README.md; if not, you can get a copy at http://Xyndravandria.ohost.de/XyndravandriaPHPLicense.txt . There might be a release under a freer license for a later, more stable version. The documentation is either included in ./admin_media/Documentation/ or can be read at http://Xyndravandria.ohost.de/Erozaver/Documentation/. All projects: Xyndravandria Averazain http://github.com/MauroDiGirolamo/Xyndravandria_Averazain PHP Averazain is an Ajax framework supporting also JavaScript disabled clients perfectly - including search engines like Google. Xyndravandria Dyverath http://github.com/MauroDiGirolamo/Xyndravandria_Dyverath PHP Dyverath is a database access wrapper. Xyndravandria Erozaver http://github.com/MauroDiGirolamo/Xyndravandria_Erozaver PHP Erozaver is a class extending the type hinting given by the PHP engine (additional support for basic type hinting and size constraints). Xyndravandria Mondraviel http://github.com/MauroDiGirolamo/Xyndravandria_Mondraviel PHP Mondraviel is a class used to separate HTML from PHP code by firstly register models - files containing place holders embedded in HTML code - and then later fill them dynamically with content by passing values for the place holders. */ namespace Xyndravandria\Erozaver; // TODO: Thing about enabling settype( ) again. /// Erozaver extends the type hinting (see /// http://de3.php.net/manual/language.oop5.typehinting.php /// to know what type hinting is) given by PHP engine: /// <ul><li>Makes basic type hinting possible</li> /// <li>Allows size constraints</li></ul> /// The syntax of size constraints is: @verbatim /// Type\Operator_Length $Variable @endverbatim /// Operator can either be SizeEqual, SizeMaximum, /// SizeMinimum or SizeInterval. @n /// When using SizeInterval, the syntax will be /// @verbatim Type\SizeInterval_Minimum_Maximum @endverbatim /// Example: @verbatim function Test( integer\SizeInterval_5_10 $Value ) { } @endverbatim /// $Value will have to be an integer and its size has /// to be between 4 and 11. @n @n /// Whenever there is an invalid argument in type and /// or length passed to a function or method, an /// XyndravandriaErozaverException is thrown. @n @n /// If you want to use size constraints within type /// hintings for your own classes, they have to /// implement the HasLength interface and, as a /// consequence, offer a Length( ) method. /// @note /// @verbatim \set_error_handler( 'Xyndravandria\Erozaver\Erozaver::HandleError' ); @endverbatim /// will be called when this class is loaded. @n /// To use your own error handler, see @ref /// Xyndravandria::Erozaver::Erozaver::RegisterHandler( ) /// "Erozaver::RegisterHandler( )". /// @abstract abstract class Erozaver { /// An exception handler which has been registered by /// a user of the framework. @n /// It is called when an Exception thrown does not /// come from the framework. /// <dl class = "type"><dt><b>%Type:</b></dt> /// <dd>callback</dd></dl> /// @private /// @static private static $UserExceptionHandler = null; /// Calls the exception handler registered in /// Erozaver::$UserExceptionHandler. /// @public /// @static /// @param array $Argument: The arguments to be passed to /// the exception handler. /// @returns mixed /// @note $Argument is an optional parameter. public static function UserExceptionHandler( array $Argument = array( ) ) { return \is_null( self::$UserExceptionHandler ) ? false : \call_user_func_array( self::$UserExceptionHandler, $Argument ); } /// An error handler which has been registered by a /// user of the framework. @n /// It is called when an error occurs which does not /// come from the framework. /// <dl class = "type"><dt><b>%Type:</b></dt> /// <dd>callback</dd></dl> /// @private /// @static private static $UserErrorHandler = null; /// Calls the error handler registered in /// Erozaver::$UserErrorHandler. /// @public /// @static /// @param array $Argument: The arguments to be passed /// to the error handler. /// @returns mixed /// @note $Argument is an optional parameter. public static function UserErrorHandler( array $Argument ) { return \is_null( self::$UserErrorHandler ) ? false : \call_user_func_array( self::$UserErrorHandler, $Argument ); } /// Used as an argument for Erozaver::RegisterHandler( ) /// to register an exception handler. const Type_ExceptionHandler = 1; /// Used as an argument for Erozaver::RegisterHandler( ) /// to register an error handler. const Type_ErrorHandler = 2; /// Registers a user handler to Erozaver. /// @public /// @static /// @param callback $Handler: The handler to be /// registered. /// @param integer $Type: The type of the handler to /// be registered. @n /// Currently, it can either be /// Erozaver::Type_ExceptionHandler or /// Erozaver::Type_ErrorHandler. public static function RegisterHandler( $Handler, $Type ) { try { $ReflectionFunction = new ReflectionFunction( $Handler ); } catch( \Exception $Exception ) { throw new XyndravandriaErozaverException( $Exception->getMessage( ) ); } if( \count( $ReflectionFunction::getParameters( ) ) != 1 ) throw new XyndravandriaErozaverException( 'The given handler wants more than one parameter.' ); elseif( $Type == self::Type_ExceptionHandler ) self::$UserExceptionHandler = $Handler; elseif( $Type == self::Type_ErrorHandler ) self::$UserErrorHandler = $Handler; else throw new XyndravandriaErozaverException( '$Type is not either Erozaver::Type_ExceptionHandler or Erozaver::Type_ErrorHandler.' ); return; } /// Method which is registered as an error handler. /// @public /// @static /// @param $Level: The error level of the error /// occured. /// @param $Message: The message of the error occured. /// @note Calls Erozaver::$UserErrorHandler if the /// error does not concern extended type hinting. public static function HandleError( $Level, $Message ) { // TODO: Replace regex with a more high-performance algorithmn based on string functions / char by char looping. if( $Level == E_RECOVERABLE_ERROR ) { // TODO: Syntax \ and namespaces within object type hints. if( ! \preg_match( '#^Argument (\d+) passed to (.+) must be an instance of (.+)((\w+)_(\w+))?, (instance of)?(\w+) given#U', $Message, $Match ) ) // TODO: Optimise regex. return false; else { list( $PartUseless, $File, $Line ) = \preg_match( '#called in (.+) on line (\d+) and defined#U', $Message, $FileInformation ) ? $FileInformation : array( '', 'Unknown', 'Unknown' ); list( $Message, $ArgumentNumber, $FunctionOrMethod, $Hint, $SizeConstraint, $Operator, $HintedSize, $Useless, $Given ) = $Match; if( ! empty( $SizeConstraint ) ) { $Hint[ \strlen( $Hint ) - 1 ] == '\\' && $Hint = \substr( $Hint, 0, \strlen( $Hint ) - 1 ); if( \in_array( $Hint, array( 'boolean', 'resource', 'NULL', 'unknown type' ) ) ) { throw new XyndravandriaErozaverException( 'Size constraints are only possible for integers, doubles, strings, arrays and objects.' ); return true; } else { $Backtrace = \debug_backtrace( ); $Argument = $Backtrace[ 1 ][ 'args' ][ $ArgumentNumber - 1 ]; $ArgumentString = ''; if( $Hint == 'array' ) $ArgumentSize = \count( $Argument ); elseif( \class_exists( $Hint ) ) { if( ! ( $Argument instanceof HasLength ) ) { throw new XyndravandriaErozaverException( 'If you want to use size constraints within type hintings for your own classes, they have to implement the HasLength interface and, as a consequence, offer a Length( ) method.' ); return true; } else $ArgumentSize = $Argument->Length( ); } else { $ArgumentString = \strval( $Argument ); \gettype( $Argument ) == 'double' && $ArgumentString = \str_replace( '.', '', $ArgumentString ); $ArgumentSize = \strlen( $ArgumentString ); } switch( $Operator ) { // TODO: Validate that $HintedSize is an integer. case 'SizeEquals' : $SizeInvalid = $ArgumentSize != $HintedSize; $OperatorError = 'hinted size and argument size are not equal'; break; case 'SizeMaximum' : $SizeInvalid = $ArgumentSize > $HintedSize; $OperatorError = 'argument size is bigger than hinted size, but should be smaller or equal'; break; case 'SizeMinimum' : $SizeInvalid = $ArgumentSize < $HintedSize; $OperatorError = 'argument size is smaller than hinted size, but should be bigger or equal'; break; case 'SizeInterval' : $Explode = explode( '_', $HintedSize ); if( \count( $Explode ) != 2 ) { throw new XyndravandriaErozaverException( 'Syntax error in type hint; missing _. File: ' . $File . '. Line: ' . $Line . '. Function or method called: ' . $FunctionOrMethod . '. Argument number: ' . $ArgumentNumber . '. Argument value: ' . ( \class_exists( $Hint ) ? '*object*' : $Argument ) . '.' ); return true; } else { list( $Minimum, $Maximum ) = $Explode; $SizeInvalid = ! ( $ArgumentSize >= $Minimum && $ArgumentSize <= $Maximum ); $OperatorError = 'argument size is ' . $ArgumentSize . ', but has to be between ( ' . $Minimum . ' - 1 ) and ( ' . $Maximum . ' + 1 )'; break; } default : throw new XyndravandriaErozaverException( 'Unknown operator \'' . $Operator . '\' within type hint. File: ' . $File . '. Line: ' . $Line . '. Function or method called: ' . $FunctionOrMethod . '. Argument number: ' . $ArgumentNumber . '. Argument value: ' . ( \class_exists( $Hint ) ? '*object*' : $Argument ) . '.' ); return true; } } if( $SizeInvalid ) { throw new XyndravandriaErozaverException( 'Invalid size of argument detected - ' . $OperatorError . '. File: ' . $File . '. Line ' . $Line . '. Function or method called: ' . $FunctionOrMethod . '. Argument number: ' . $ArgumentNumber . '. Argument value: ' . ( \class_exists( $Hint ) ? '*object*' : $Argument ) . '. Operator: ' . $Operator . '. Hinted size: ' . $HintedSize . '. Argument size: ' . $ArgumentSize . '.' ); return true; } } return $Hint == $Given ? true : Erozaver::UserErrorHandler( array( $Level, $Message ) ); } } else return false; } } \set_error_handler( 'Xyndravandria\Erozaver\Erozaver::HandleError' ); ?>