Skip to content

Instantly share code, notes, and snippets.

@bastman
Created November 25, 2012 12:07
Show Gist options
  • Save bastman/4143253 to your computer and use it in GitHub Desktop.
Save bastman/4143253 to your computer and use it in GitHub Desktop.
Bootstrapping prototype
class Bootstrap
{
// PROTOTYPE. EXPERIMENTAL. BUGGY!
protected $_exceptionHandler;
protected $_errorHandler;
protected $_shutdownHandler;
protected $_onException;
protected $_onError;
protected $_onShutdownResult;
protected $_onShutdownError;
protected $_errorReportingCaptureLevel;
protected $_errorMessageShutdownFailed = 'ERROR_BOOTSRAP_SHUTDOWN_FAILED';
/**
* @return string
*/
public function getErrorMessageShutDownFailed()
{
return $this->_errorMessageShutdownFailed;
}
public function setOnException($callable)
{
$result = $this;
if ($callable === null) {
$this->_onException = null;
}
if(!is_callable($callable)) {
throw new InvalidArgumentException('callable must be callable or null');
}
$this->_onException = $callable;
return $result;
}
public function setOnError($callable)
{
$result = $this;
if ($callable === null) {
$this->_onError = null;
}
if(!is_callable($callable)) {
throw new InvalidArgumentException('callable must be callable or null');
}
$this->_onError = $callable;
return $result;
}
public function setErrorReportingCaptureLevel($captureLevel)
{
if($captureLevel === null) {
$captureLevel = $this->createErrorReportingCaptureLevel();
}
$this->_errorReportingCaptureLevel = $captureLevel;
error_reporting($captureLevel);
return $this;
}
public function resetReportingCaptureLevel()
{
$this->setErrorReportingCaptureLevel(null);
return $this;
}
private static $_instance;
/**
* @return Bootstrap
*/
public function getInstance() {
if(!self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function init()
{
$this
->resetReportingCaptureLevel()
->resetErrorHandler()
->resetExceptionHandler()
->resetShutdownHandler()
;
return $this;
}
/**
* @return int
*/
private function createErrorReportingCaptureLevel()
{
return ( (E_ALL|E_STRICT) );
}
private function createErrorHandler()
{
$handler = function($errno, $errstr, $errfile, $errline) {
$customHandler = $this->_onError;
if(is_callable($customHandler)) {
$isHandled = call_user_func_array(
$customHandler,
array(
$this,
$errno, $errstr, $errfile, $errline
)
);
$isHandled = ($isHandled===true);
if($isHandled) {
return true;
}
}
switch($errno) {
case null:
case 0:
case E_WARNING: {
return true;
}
default: break;
}
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
};
return $handler;
}
public function resetErrorHandler()
{
$this->setErrorHandler(null);
return $this;
}
public function setErrorHandler($callable)
{
$handler = $callable;
if ($callable === null) {
$handler = $this->createErrorHandler();
}
if (!is_callable($callable)) {
throw new InvalidArgumentException('Callable must be callable or null');
}
$this->_errorHandler = $handler;
set_error_handler($handler);
return $this;
}
private function createExceptionHandler()
{
$handler = function(Exception $exception) {
$customHandler = $this->_onException;
if(is_callable($customHandler)) {
$isHandled = call_user_func_array(
$customHandler,
array(
$this,
$exception
)
);
$isHandled = ($isHandled===true);
if($isHandled) {
return true;
}
}
return true;
};
return $handler;
}
public function resetExceptionHandler()
{
$this->setExceptionHandler(null);
return $this;
}
public function setExceptionHandler($callable)
{
$handler = $callable;
if ($callable === null) {
$handler = $this->createExceptionHandler();
}
if (!is_callable($callable)) {
throw new InvalidArgumentException('Callable must be callable or null');
}
$this->_exceptionHandler = $handler;
set_exception_handler($handler);
return $this;
}
private function createShutdownHandler()
{
$handler = function(Exception $exception) {
$result = true;
$isShuttingdown = true;
$lastError = error_get_last();
$hasError = is_array($lastError);
$shutdownException = null;
try {
if(!$hasError) {
$customHandler = $this->_onShutdownResult;
if(is_callable($customHandler)) {
$isHandled = call_user_func_array(
$customHandler,
array(
$this,
$lastError,
$isShuttingdown
)
);
$isHandled = ($isHandled===true);
if($isHandled) {
return $result;
}
}
}
}catch(Exception $e) {
$shutdownException = $e;
}
$hasError = ($hasError||($shutdownException instanceof Exception));
if($hasError) {
try {
$customHandler = $this->_onShutdownError;
if(is_callable($customHandler)) {
$isHandled = call_user_func_array(
$customHandler,
array(
$this,
$shutdownException,
$lastError,
$isShuttingdown
)
);
$isHandled = ($isHandled===true);
if($isHandled) {
return $result;
}
}
}catch(Exception $e) {
$errrorMessage = $this->getErrorMessageShutdownFailed();
if((is_string($errrorMessage)) && ($errrorMessage!=='')) {
echo $errrorMessage;
return false;
}
}
}
return $result;
};
return $handler;
}
public function resetShutdownHandler()
{
$this->setShutdownHandler(null);
return $this;
}
public function setShutdownHandler($callable)
{
$handler = $callable;
if ($callable === null) {
$handler = $this->createShutdownHandler();
}
if (!is_callable($callable)) {
throw new InvalidArgumentException('Callable must be callable or null');
}
$this->_shutdownHandler = $handler;
register_shutdown_function($handler);
return $this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment