[code]<?php
/**
 * Hiermee worden standaard PHP-meldingen omgezet naar Exceptions,
 * zo is het makkelijker af te vangen binnen objectgeorienteerde applicaties
 *
 * Gebruik:
 * <pre>Error_Handler::init()
 *     // in principe hetzelfde als error_reporting()
 *     ->setBitField(E_ALL)
 *     // de zwaarheid van iedere melding
 *     ->setSeverity(array(
 *         E_USER_ERROR        => 100,
 *         E_RECOVERABLE_ERROR => 90,
 *         E_WARNING           => 80,
 *         E_USER_WARNING      => 70,
 *         // etc.
 *     ));</pre>
 */
class Error_Handler {
	/**
	 * De zwaarheid per melding
	 *
	 * @var array
	 */
	protected $_severityPerError = array(
		E_WARNING           => 0,
		E_NOTICE            => 0,
		E_USER_ERROR        => 0,
		E_USER_WARNING      => 0,
		E_USER_NOTICE       => 0,
		E_STRICT            => 0,
		E_RECOVERABLE_ERROR => 0
	);
	/**
	 * Het bitfield, als een melding hiermee matcht wordt deze als
	 * Exception gegooid
	 *
	 * @var int
	 */
	protected $_bitField = 0;

	/**
	 * Initialiseer de error_handler
	 *
	 * Deze maakt ook, indien deze bestaan, de E_DEPRECATED en
	 * E_USER_DEPRECATED entries aan in {@link $this->_severityPerError}
	 *
	 * @return Error_Handler
	 */
	static public function init() {
		// de nieuwe instance
		$instance = new self;

		// compatibility met nieuwe PHP versies
		if(defined('E_DEPRECATED')) {
			$instance->_severityPerError[E_DEPRECATED] = 0;
		}
		if(defined('E_USER_DEPRECATED')) {
			$instance->_severityPerError[E_USER_DEPRECATED] = 0;
		}

		// retourneer de nieuwe instantie
		return $instance;
	}

	/**
	 * Stel het bitfield in waaraan meldingen moeten voldoen om gegooid te worden
	 *
	 * In principe hetzelfde als error_reporting($bitfield)
	 *
	 * @param int $bitfield
	 * @return Error_Handler
	 */
	public function setBitField($bitfield) {
		if(!is_int($bitfield)) {
			throw new ErrorException('Bitfield must be of type integer');
		}

		$this->_bitField = $bitfield;

		return $this;
	}

	/**
	 * Stel de zwaarheid in per melding
	 *
	 * @param int|array $error Ofwel een E_***-constante, ofwel een array
	 * @param int $severity De zwaarheid
	 * @return Error_Handler
	 */
	public function setSeverity($error, $severity = null) {
		if(($severity === null && !is_array($error)) && !(is_int($error) && !is_int($severity))) {
			throw new ErrorException('setSeverity() accepts only two integers or an array');
		}
		if($severity === null) {
			foreach($error as $key => $value) {
				$this->setSeverity($key, $value);
			}
		} else {
			$this->_severityPerError[$error] = $severity;
		}

		return $this;
	}

	/**
	 * De constructor van deze klasse
	 *
	 * Stelt de error_handler in
	 */
	protected function __construct() {
		set_error_handler(array($this, 'handleError'));
	}

	/**
	 * De handler die wordt aangeroepen bij een melding
	 *
	 * @param int $errno
	 * @param string $errstr
	 * @param string $errfile
	 * @param int $errline
	 * 
	 * @throws ErrorException
	 */
	public function handleError($errno, $errstr, $errfile, $errline) {
		if($this->_bitField & $errno) {
			throw new ErrorException($errstr, $this->_severityPerError[$errno], $errno, $errfile, $errline);
		}
	}
}

// initialiseer de errorhandler
Error_Handler::init()
	// stel het bitfield in op alleen warnings
	->setBitfield(E_WARNING)
	// stel de zwaarheid van E_WARNING in op 10
	->setSeverity(array(
		E_WARNING => 10
	));

// een nutteloze variabele om te testen
$text = 'bla';

try {
	// bogus tekst, dit werkt natuurlijk
	echo 'Aap noot mies?<br />';
	// een entry poppen van een string? Hier komt de exceptie
	echo array_pop($text) . '<br />';
} catch(ErrorException $e) {
	// output, zoals gewoonlijk
	echo '<code><i>' . $e->getMessage() . '</i> op regel <b>' . $e->getLine()
	   . '</b> van bestand <b>' . $e->getFile() . '</b></code><br />';
}[/code]