ラボ > FuelPHP:独自クラスやCoreクラスの継承

Fuelphp 「Core\classes\Errorhandler」を継承

作成日:2018-03-05, 更新日:2018-03-14

基本

1.「fuelphp\core\classes\errorhandler.php」を複製→「fuelphp\app\classes\errorhandler.php」
2.「fuelphp\app\classes\errorhandler.php」の修正
3.「fuelphp\app\bootstrap.php」の修正

FuelPHPのバージョンによっては「errorhandler.php」じゃなく「error.php」。
中身も「class Errorhandler」ではなく「class Error」になっている箇所があるので適宜変更。
※FuelPHP1.8あたりから「errorhandler.php」になったっぽい。

「fuelphp\app\classes\errorhandler.php」の修正

namespaceや継承の設定。

略

//namespace Fuel\Core; // ←コメント

略

// class PhpErrorException
class PhpErrorException extends \Fuel\Core\PhpErrorException // ←継承元の指定

略

// class Errorhandler
class Errorhandler extends \Fuel\Core\Errorhandler // ←継承元の指定

以下、略

「fuelphp\app\bootstrap.php」の修正

\Autoloader::add_classes(array(
   // Add classes you want to override here
   // Example: 'View' => APPPATH.'classes/view.php',
   'PhpErrorException' => APPPATH.'classes/errorhandler.php',
   'Errorhandler' => APPPATH.'classes/errorhandler.php',
));

各種調整

エラーがあったときは「shutdown_handler()」に入るっぽいので、何か処理を加えるならこの関数を起点に考えるのが良さげ。
もしくは画面出力が「show_php_error()」と「show_production_error()」にあたるので、コチラを起点に考える。

PRODUCTIONのときのエラーが「Oops!」だから変更したい

・「core\views\errors\production.php」をコピペして「app\views\errors\production.php」

「app/classes/errorhandler.php」の「shutdown_handler()」から各エラー処理を行っているっぽいので、ココを元に処理(例えば「DBに保存、メール送信させる」等)を追加などすれば良さげ。

PRODUCTIONのときのエラー時にメール送信させたい

・「show_php_error()」を複製して「makeEmailBody()」を作成→内容は「データだけ返す」って感じ。
・「show_production_error()」の中で「$is_cli」じゃないときにメール送信させるようにする。

▼「fuelphp\app\classes\errorhandler.php」:下記のソースは古いバージョンなのでそのままコピペするのはダメ。

~ 略 ~
public static function makeEmailBody(\Exception $e)
{
  $fatal = (bool) ( ! in_array($e->getCode(), \Config::get('errors.continue_on', array())));
  $data = static::prepare_exception($e, $fatal);

  if ($fatal)
  {
    $data['contents'] = ob_get_contents();
    while (ob_get_level() > 0)
    {
      ob_end_clean();
    }
    ob_start(\Config::get('ob_callback', null));
  }
  else
  {
    static::$non_fatal_cache[] = $data;
  }

  //if (\Fuel::$is_cli)
  //{
  //  \Cli::write(\Cli::color($data['severity'].' - '.$data['message'].' in '.\Fuel::clean_path($data['filepath']).' on line '.$data['error_line'], 'red'));
  //  if (\Config::get('cli_backtrace'))
  //  {
  //    \Cli::write('Stack trace:');
  //    \Cli::write(\Debug::backtrace($e->getTrace()));
  //  }
  //  return;
  //}

  if ($fatal)
  {
    if ( ! headers_sent())
    {
      $protocol = \Input::server('SERVER_PROTOCOL') ? \Input::server('SERVER_PROTOCOL') : 'HTTP/1.1';
      // header($protocol.' 500 Internal Server Error');
      
      $data['protocol'] = $protocol.' 500 Internal Server Error';
    }

    $data['non_fatal'] = static::$non_fatal_cache;

    //try
    //{
    //  exit(\View::forge('errors'.DS.'php_fatal_error', $data, false));
    //}
    //catch (\FuelException $view_exception)
    //{
    //  exit($data['severity'].' - '.$data['message'].' in '.\Fuel::clean_path($data['filepath']).' on line '.$data['error_line']);
    //}
  }

  return $data;
  
  //try
  //{
  //  echo \View::forge('errors'.DS.'php_error', $data, false);
  //}
  //catch (\FuelException $e)
  //{
  //  echo $e->getMessage().'<br />';
  //}
}

/**
 * Shows the errors/production view and exits.  This only gets
 * called when an error occurs in production mode.
 *
 * @return  void
 */
public static function show_production_error(\Exception $e)
{
  // when we're on CLI, always show the php error
  if (\Fuel::$is_cli)
  {
    return static::show_php_error($e);
  }

  // send-mail
  $emailData = self::makeEmailBody($e);
  →この「$emailData」をメール本文にセットして送信。配列だから文字列に変換してあげるか何かする。
  
  if ( ! headers_sent())
  ~ 以下、略 ~

※このソースは古いバージョンで使ったソース。「public static」→「protected static」などと微妙に違う。

関連項目

FuelPHPでcoreクラスを継承したい