PHP Classes
Icontem

File: TypeHintHandler.php


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Martin Alterisio  >  Type Hint Class  >  TypeHintHandler.php  
File: TypeHintHandler.php
Role: Class source
Content type: text/plain
Description: TypeHints handler.
Class: Type Hint Class
Implement type hinting support for base PHP types
 

Contents

Class file image Download
<?php
/**
 * @package typehintclass
 */

/**
 * Class that handles type hinting errors and checks type hint
 * classes. Singleton.
 */
final class TypeHintHandler {
    
/**
     * Error handler that was replaced by the one from this object
     * @var function|null
     */
    
private $oldErrorHandler;
    
/**
     * Cached info parsed from error message.
     * @var array
     */
    
private $parsedErrors;
    
/**
     * Cached results of checking which classes are type hints.
     * @var array
     */
    
private $typeHintClasses;
    
    
/**
     * Constructor. Activates the error handling.
     */
    
private function __construct() {
        
$this->oldErrorHandler set_error_handler(array($this'errorHandler'));
        
$this->parsedErrors = array();
        
$this->typeHintClasses = array();
    }
    
    
/**
     * Single instance of TypeHintHandler.
     * @var TypeHintHandler
     */
    
private static $instance;
    
    
/**
     * Sets up the single instance of this handler.
     */
    
public static function setUp() {
        if (
self::$instance === null) {
            
self::$instance = new TypeHintHandler();
        }
    }
    
    
/**
     * Returns the single instance of this handler.
     * @return TypeHintHandler The singleton instance.
     */
    
public static function getInstance() {
        
self::setUp();
        return 
self::$instance;
    }
    
    
/**
     * Parses an error string to find out if it is a type hint failure
     * and to gather the info about this error in particular.
     * @param string $errstr Error message.
     * @return array|null Info on the parsed error.
     */
    
private function parseErrorString($errstr) {
        if (isset(
$this->parsedErrors[$errstr])) {
            return 
$this->parsedErrors[$errstr];
        }
        
$parsedError null;
        if (
preg_match('/^Argument ([0-9]+) passed to ([a-zA-Z0-9_:]+)\(\) must be an instance of ([a-zA-Z0-9_:]+),/'$errstr$match)) {
            
$parsedError = array(
                
'argnum'   => $match[1],
                
'class'    => null,
                
'function' => $match[2],
                
'typehint' => $match[3],
            ); 
            if (
preg_match('/^([a-zA-Z0-9_]+)::([a-zA-Z0-9_]+)$/'$match[2], $match)) {
                
$parsedError['class'] = $match[1];
                
$parsedError['function'] = $match[2];
            }
        }
        
$this->parsedErrors[$errstr] = $parsedError;
        return 
$parsedError;
    }
    
    
/**
     * Error handling routine.
     * @private
     * @param int $errno Error code.
     * @param string $errstr Error message.
     * @param string $errfile File where the error occurred.
     * @param int $errline The line number where the error occurred.
     * @param array $errcontext The context where the error occurred.
     */
    
public function errorHandler($errno$errstr$errfile$errline$errcontext) {
        if (
$errno == E_RECOVERABLE_ERROR) {
            if (
$parsedError $this->parseErrorString($errstr)) {
                
$backtrace debug_backtrace();
                
$value = @$backtrace[1]['args'][$parsedError['argnum']-1];
                if (
$this->solveTypeHintFailure($parsedError['typehint'], $value)) {
                    return;
                }
            }
        }
        if (
$this->oldErrorHandler) {
            return 
call_user_func($this->oldErrorHandler$errno$errstr$errfile$errline$errcontext);
        } else {
            return 
false;
        }
    }
    
    
/**
     * Solves a type hint failure, deciding to continue or not.
     * @param string $typeHint The type hint used.
     * @param mixed $value The value that failed the type hint.
     * @return bool Whether to continue or not.
     */
    
private function solveTypeHintFailure($typeHint$value) {
        if (
$this->isTypeHintClass($typeHint)) {
            return 
call_user_func(array($typeHint'isTypeHintFor'), $value);
        }
        return 
false;
    }
    
    
/**
     * Indicates if a class is a type hint class.
     * 
     * @param string $className The class.
     * @return bool True if the class is a type hint class.
     */
    
public function isTypeHintClass($className) {
        if (isset(
$this->typeHintClasses[$className])) {
            return 
$this->typeHintClasses[$className];
        }
        
$this->typeHintClasses[$className] = false;
        if (
class_exists($className)) {
            if (
in_array('TypeHint'class_implements($className))) {
                
$this->typeHintClasses[$className] = true;
            }
        }
        return 
$this->typeHintClasses[$className];
    }
}
?>

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products