[PHP]error_get_last関数の詳細解説

PHP

こんにちは!今回は、PHPのerror_get_last関数について詳しく解説していきます。

error_get_last関数とは?

error_get_last関数は、最後に発生したエラーの情報を配列として取得する関数です。エラーが発生していない場合はnullを返します。

基本構文

array|null error_get_last ( void )

返り値の配列構造

array(
    'type' => エラーの種類,
    'message' => エラーメッセージ,
    'file' => エラーが発生したファイル,
    'line' => エラーが発生した行番号
)

基本的な使用例

1. シンプルな使用例

<?php
// エラーを発生させる
@file_get_contents("non_existent_file.txt");

// エラー情報を取得
$error = error_get_last();
if ($error !== null) {
    echo "エラータイプ: " . $error['type'] . "\n";
    echo "メッセージ: " . $error['message'] . "\n";
    echo "ファイル: " . $error['file'] . "\n";
    echo "行番号: " . $error['line'] . "\n";
}
?>

実践的な使用例

1. エラーハンドリングクラス

<?php
class ErrorHandler {
    public function execute(callable $callback) {
        // エラー情報をクリア
        error_clear_last();

        // 処理を実行
        $result = @$callback();

        // エラー情報を取得
        $error = error_get_last();

        return [
            'success' => ($error === null),
            'result' => $result,
            'error' => $error
        ];
    }
}

// 使用例
$handler = new ErrorHandler();
$result = $handler->execute(function() {
    return file_get_contents("config.txt");
});

if (!$result['success']) {
    echo "エラーが発生しました: " . $result['error']['message'];
}
?>

2. ファイル操作のエラーハンドリング

<?php
class FileManager {
    public function readFile($filepath) {
        error_clear_last();
        $content = @file_get_contents($filepath);
        $error = error_get_last();

        if ($error) {
            throw new Exception(sprintf(
                "ファイル読み込みエラー: %s (%s: %d)",
                $error['message'],
                $error['file'],
                $error['line']
            ));
        }

        return $content;
    }

    public function writeFile($filepath, $content) {
        error_clear_last();
        $result = @file_put_contents($filepath, $content);
        $error = error_get_last();

        if ($error) {
            throw new Exception(
                "ファイル書き込みエラー: " . $error['message']
            );
        }

        return $result;
    }
}
?>

3. エラーロギングシステム

<?php
class ErrorLogger {
    private $logFile;

    public function __construct($logFile) {
        $this->logFile = $logFile;
    }

    public function logLastError() {
        $error = error_get_last();
        if ($error) {
            $message = sprintf(
                "[%s] %s in %s on line %d\n",
                date('Y-m-d H:i:s'),
                $error['message'],
                $error['file'],
                $error['line']
            );

            file_put_contents($this->logFile, $message, FILE_APPEND);
            return true;
        }
        return false;
    }
}
?>

エラータイプの判定

1. エラータイプの定数マッピング

<?php
class ErrorTypeMapper {
    private static $errorTypes = [
        E_ERROR => 'Error',
        E_WARNING => 'Warning',
        E_PARSE => 'Parse Error',
        E_NOTICE => 'Notice',
        E_CORE_ERROR => 'Core Error',
        E_CORE_WARNING => 'Core Warning',
        E_COMPILE_ERROR => 'Compile Error',
        E_COMPILE_WARNING => 'Compile Warning',
        E_USER_ERROR => 'User Error',
        E_USER_WARNING => 'User Warning',
        E_USER_NOTICE => 'User Notice',
        E_STRICT => 'Strict',
        E_RECOVERABLE_ERROR => 'Recoverable Error',
        E_DEPRECATED => 'Deprecated',
        E_USER_DEPRECATED => 'User Deprecated'
    ];

    public static function getErrorTypeName($type) {
        return self::$errorTypes[$type] ?? 'Unknown Error';
    }
}

// 使用例
$error = error_get_last();
if ($error) {
    echo "エラータイプ: " . ErrorTypeMapper::getErrorTypeName($error['type']);
}
?>

2. エラー重要度による処理分岐

<?php
function handleError($error) {
    if (!$error) return;

    switch ($error['type']) {
        case E_ERROR:
        case E_CORE_ERROR:
        case E_COMPILE_ERROR:
        case E_USER_ERROR:
            // 致命的エラーの処理
            logCriticalError($error);
            die("致命的なエラーが発生しました");
            break;

        case E_WARNING:
        case E_CORE_WARNING:
        case E_COMPILE_WARNING:
        case E_USER_WARNING:
            // 警告の処理
            logWarning($error);
            break;

        case E_NOTICE:
        case E_USER_NOTICE:
            // 注意の処理
            logNotice($error);
            break;
    }
}
?>

高度な使用例

1. エラーモニタリングシステム

<?php
class ErrorMonitor {
    private $errors = [];
    private $maxErrors;

    public function __construct($maxErrors = 100) {
        $this->maxErrors = $maxErrors;
    }

    public function monitor(callable $callback) {
        error_clear_last();
        $result = @$callback();
        $error = error_get_last();

        if ($error) {
            $this->addError($error);
        }

        return $result;
    }

    private function addError($error) {
        $this->errors[] = array_merge($error, [
            'timestamp' => time()
        ]);

        // 最大数を超えた古いエラーを削除
        if (count($this->errors) > $this->maxErrors) {
            array_shift($this->errors);
        }
    }

    public function getErrors() {
        return $this->errors;
    }
}
?>

2. エラー統計収集

<?php
class ErrorStatistics {
    private $stats = [];

    public function collect($error) {
        if (!$error) return;

        $key = $error['file'] . ':' . $error['line'];

        if (!isset($this->stats[$key])) {
            $this->stats[$key] = [
                'count' => 0,
                'type' => $error['type'],
                'message' => $error['message'],
                'first_seen' => time(),
                'last_seen' => time()
            ];
        }

        $this->stats[$key]['count']++;
        $this->stats[$key]['last_seen'] = time();
    }

    public function getStatistics() {
        return $this->stats;
    }
}
?>

まとめ

error_get_last関数の主なポイント:

  1. 最後に発生したエラー情報を取得可能
  2. エラーが発生していない場合はnullを返す
  3. エラータイプ、メッセージ、ファイル、行番号の情報を含む
  4. エラーハンドリングシステムの構築に有用

活用シーン:

  • エラーログの作成
  • デバッグ情報の収集
  • エラーモニタリング
  • エラー統計の収集

注意点:

  • error_clear_lastと組み合わせて使用すると効果的
  • エラータイプに応じた適切な処理分岐
  • ログローテーションなどの考慮

これらの点を理解して使用することで、より効果的なエラーハンドリングが実装できます。

以上で、error_get_last関数の解説を終わります。
ご質問やご不明点があれば、お気軽にコメントしてください!

タイトルとURLをコピーしました