Skip to content

Instantly share code, notes, and snippets.

@k-holy
Created March 5, 2012 10:28
Show Gist options
  • Save k-holy/1977779 to your computer and use it in GitHub Desktop.
Save k-holy/1977779 to your computer and use it in GitHub Desktop.
Volcanus/Error
<?php
namespace Acme;
use Volcanus\Error;
class U
{
public static function H($data, $filter = null)
{
$var = (isset($data))
? htmlspecialchars($data, ENT_QUOTES, 'UTF-8')
: null;
return (is_callable($filter))
? $filter($var)
: $var;
}
}
$vendor_dir = realpath(__DIR__ . '/../../app/vendor');
$log_dir = realpath(__DIR__ . '/../../app/log');
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
// オートロード
require_once $vendor_dir . '/Volcanus_Utils/src/Volcanus/Loader.php';
spl_autoload_register(\Volcanus\Loader::getInstance(array(
'Volcanus' => array(realpath($vendor_dir . '/Volcanus_Utils/src')),
'Volcanus\Validation' => array(realpath($vendor_dir . '/Volcanus_Validation/src')),
)), true, true);
// エラー設定
$error = new Error(array(
'output_encoding' => 'UTF-8',
'log_level' => Error::LEVEL_ALL,
'display_level' => Error::LEVEL_ALL,
'forward_level' => Error::LEVEL_EXCEPTION | Error::LEVEL_ERROR,
'display_html' => true,
'display_buffering' => true,
));
// エラーログ
$log_file = $log_dir . DIRECTORY_SEPARATOR . 'volcanus_' . date('Ym') . '.log';
$error->setLogger(function($message) use ($log_file) {
error_log(sprintf("[%s] %s\n", date('Y-m-d H:i:s'), $message), 3, $log_file);
});
// エラー画面
$error->setForward(function($message) {
$status = '500 Internal Server Error';
if (!headers_sent()) {
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status);
}
$body = <<< HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>%s</title>
</head>
<body>
<h1>%s</h1>
<h2>システムエラーが発生しました。</h2>
<hr />
<p><a href="%s">戻る</a></p>
</body>
</html>
HTML;
echo sprintf($body,
U::H($status),
U::H($status),
U::H($_SERVER['REQUEST_URI']));
exit();
});
// 例外ハンドラ&エラーハンドラ登録
set_error_handler($error->getErrorHandler());
set_exception_handler($error->getExceptionHandler());
<?php
namespace Acme;
class U
{
public static function H($data, $filter = null)
{
$var = (isset($data))
? htmlspecialchars($data, ENT_QUOTES, 'UTF-8')
: null;
return (is_callable($filter))
? $filter($var)
: $var;
}
public static function formatTrace($trace)
{
$stack = array();
$format_var = function($var) {
if (is_null($var)) {
return 'NULL';
}
if (is_int($var)) {
return sprintf('Int(%d)', $var);
}
if (is_float($var)) {
return sprintf('Float(%F)', $var);
}
if (is_string($var)) {
return sprintf('"%s"', $var);
}
if (is_bool($var)) {
return sprintf('Bool(%s)', $var ? 'true' : 'false');
}
if (is_array($var)) {
return 'Array';
}
if (is_object($var)) {
return sprintf('Object(%s)', get_class($var), $var);
}
return sprintf('%s', gettype($var));
};
foreach ($trace as $i => $t) {
$args = '';
if (isset($t['args']) && !empty($t['args'])) {
$args = implode(', ', array_map(function($arg) use ($format_var) {
if (is_array($arg)) {
$vars = array();
foreach ($arg as $key => $var) {
$vars[] = sprintf('%s=>%s',
$format_var($key), $format_var($var));
}
return sprintf('Array[%s]', implode(', ', $vars));
}
return $format_var($arg);
}, $t['args']));
}
$stack[] = sprintf('#%d %s(%d): %s%s%s(%s)',
$i,
(isset($t['file' ])) ? $t['file' ] : '',
(isset($t['line' ])) ? $t['line' ] : '',
(isset($t['class' ])) ? $t['class' ] : '',
(isset($t['type' ])) ? $t['type' ] : '',
(isset($t['function'])) ? $t['function'] : '',
$args);
}
return $stack;
}
public static function errorForward()
{
$status = '500 Internal Server Error';
if (!headers_sent()) {
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status);
}
$body = <<< HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>%s</title>
</head>
<body>
<h1>%s</h1>
<h2>システムエラーが発生しました。</h2>
<hr />
<p><a href="%s">戻る</a></p>
</body>
</html>
HTML;
echo sprintf($body,
U::H($status),
U::H($status),
U::H($_SERVER['REQUEST_URI']));
exit();
}
}
$vendor_dir = realpath(__DIR__ . '/../../app/vendor');
$log_dir = realpath(__DIR__ . '/../../app/log');
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
// オートロード
require_once $vendor_dir . '/Volcanus_Utils/src/Volcanus/Loader.php';
spl_autoload_register(\Volcanus\Loader::getInstance(array(
'Volcanus' => array(realpath($vendor_dir . '/Volcanus_Utils/src')),
'Volcanus\Validation' => array(realpath($vendor_dir . '/Volcanus_Validation/src')),
)), true, true);
// ログ
$log_file = $log_dir . DIRECTORY_SEPARATOR . 'volcanus_' . date('Ym') . '.log';
$logger = function($message) use ($log_file) {
$log_message = sprintf("[%s] %s\n", date('Y-m-d H:i:s'), $message);
error_log($log_message , 3, $log_file);
};
// 例外ハンドラ
set_exception_handler(function($exception) use ($logger) {
$message = sprintf("Fatal Error: Uncaught exception '%s' with message '%s' in %s:%d\nStack trace:\n%s thrown in %s on line %d",
get_class($exception),
$exception->getMessage(),
$exception->getFile(),
$exception->getLine(),
implode("\n", U::formatTrace($exception->getTrace())),
$exception->getFile(),
$exception->getLine());
if (ini_get('display_errors')) {
echo '<pre>' . U::H($message) . '</pre>';
}
$logger($message);
U::errorForward();
});
// エラーハンドラ
set_error_handler(function($errno, $errstr, $errfile, $errline) use ($logger) {
$titles = array (
E_ERROR => 'Fatal error',
E_WARNING => 'Warning',
E_NOTICE => 'Notice',
E_STRICT => 'Strict standards',
E_RECOVERABLE_ERROR => 'Catchable fatal error',
E_DEPRECATED => 'Depricated',
E_USER_ERROR => 'Fatal error (User)',
E_USER_WARNING => 'Warning (User)',
E_USER_NOTICE => 'Notice (User)',
E_USER_DEPRECATED => 'Depricated (User)',
);
$message = sprintf('%s: %s in %s on line %d',
(isset($titles[$errno])) ? $titles[$errno] : 'Unknown error',
$errstr,
$errfile,
$errline
);
$trace = debug_backtrace();
$stackTrace = U::formatTrace($trace);
if (!empty($stackTrace)) {
$message .= sprintf("\nStack trace:\n%s", implode("\n", $stackTrace));
}
$logger($message);
if (error_reporting() & $errno) {
if (ini_get('display_errors')) {
echo '<pre>' . U::H($message) . '</pre>';
}
if ((E_ERROR | E_USER_ERROR) & $errno) {
U::errorForward();
}
}
return true;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment