Changeset 21465


Ignore:
Timestamp:
2012/02/09 16:52:16 (9 years ago)
Author:
Seasoft
Message:

#1633 (エラーハンドリングの改善)
#1605 (PHP4向けコードの除去、PHP5向けのコード最適化)
#811 (出力バッファリングの利用を見直し)
#1625 (typo修正・ソース整形・ソースコメントの改善)

Location:
branches/version-2_12-dev
Files:
6 edited
1 moved

Legend:

Unmodified
Added
Removed
  • branches/version-2_12-dev/data/app_initial.php

    r20764 r21465  
    3737} 
    3838 
     39require_once CLASS_EX_REALDIR . 'helper_extends/SC_Helper_HandleError_Ex.php'; 
     40SC_Helper_HandleError_Ex::load(); 
     41 
    3942require_once CLASS_EX_REALDIR . 'SC_Initial_Ex.php'; 
    4043// アプリケーション初期化処理 
  • branches/version-2_12-dev/data/class/SC_Initial.php

    r21460 r21465  
    113113     */ 
    114114    function phpconfigInit() { 
    115         ini_set('display_errors', '1'); 
    116115        ini_set('html_errors', '1'); 
    117116        ini_set('mbstring.http_input', CHAR_CODE); 
  • branches/version-2_12-dev/data/class/helper/SC_Helper_HandleError.php

    r21429 r21465  
    2222 */ 
    2323 
    24 // E_DEPRECATED 定数 (for PHP < 5.3) 
    25 // TODO バージョン互換処理に統合したい。 
    26 if (!defined('E_DEPRECATED')) { 
    27     define('E_DEPRECATED', 8192); 
     24/** 
     25 * エラーハンドリングのクラス 
     26 * 
     27 * @package Page 
     28 * @version $Id$ 
     29 */ 
     30class SC_Helper_HandleError { 
     31 
     32    /** 
     33     * 処理の読み込みを行う 
     34     * 
     35     * @return void 
     36     */ 
     37    static function load() { 
     38        // E_DEPRECATED 定数 (for PHP < 5.3) 
     39        // TODO バージョン互換処理に統合したい。 
     40        if (!defined('E_DEPRECATED')) { 
     41            define('E_DEPRECATED', 8192); 
     42        } 
     43 
     44        // エラーレベル設定 
     45        // 開発時は E_ALL を推奨 
     46        error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE & ~E_DEPRECATED); 
     47 
     48        if (!defined('SAFE') || SAFE !== true || !defined('INSTALL_FUNCTION') || INSTALL_FUNCTION !== true) { 
     49            // E_WARNING, E_USER_WARNING を捕捉した場合にログを残すためのエラーハンドラ 
     50            set_error_handler(array(__CLASS__, 'handle_warning')); 
     51 
     52            // 実質的に PHP 5.2 以降かで処理が分かれる 
     53            if (function_exists('error_get_last')) { 
     54                // E_USER_ERROR を捕捉した場合にエラー画面を表示させるためのエラーハンドラ 
     55                register_shutdown_function(array(__CLASS__, 'handle_error')); 
     56                // 以降の処理では画面へのエラー表示は行なわない 
     57                ini_set('display_errors' , 0); 
     58            } else { 
     59                // エラー捕捉用の出力バッファリング 
     60                ob_start(array(__CLASS__, '_fatal_error_handler')); 
     61                ini_set('display_errors' , 1); 
     62            } 
     63        } 
     64    } 
     65 
     66    /** 
     67     * 警告や E_USER_ERROR を捕捉した場合にエラー画面を表示させるエラーハンドラ関数. 
     68     * 
     69     * この関数は, set_error_handler() 関数に登録するための関数である. 
     70     * trigger_error にて E_USER_ERROR が生成されると, エラーログを出力した後, 
     71     * エラー画面を表示させる. 
     72     * E_WARNING, E_USER_WARNING が発生した場合、ログを記録して、true を返す。 
     73     * (エラー画面・エラー文言は表示させない。) 
     74     * 
     75     * @param integer $errno エラーコード 
     76     * @param string $errstr エラーメッセージ 
     77     * @param string $errfile エラーが発生したファイル名 
     78     * @param integer $errline エラーが発生した行番号 
     79     * @return void|boolean E_USER_ERROR が発生した場合は, エラーページへリダイレクト; 
     80     *                      E_WARNING, E_USER_WARNING が発生した場合、true を返す 
     81     */ 
     82    static function handle_warning($errno, $errstr, $errfile, $errline) { 
     83 
     84        // error_reporting 設定に含まれていないエラーコードは処理しない 
     85        if (!(error_reporting() & $errno)) { 
     86            return; 
     87        } 
     88 
     89        $now = date("Y/m/d H:i:s"); 
     90        // 本来 realpath() で正規化したいところだが、NULL を返すケースがあるため避けている (#1618) 
     91        $log_file_path = DATA_REALDIR . 'logs/site.log'; 
     92        switch ($errno) { 
     93            case E_USER_ERROR: 
     94                $message = $now . " [$errfile:$errline] FATAL Error($errno) $errstr from ". $_SERVER['REMOTE_ADDR'] . "\n"; 
     95                error_log($message, 3, $log_file_path); 
     96     
     97                self::displaySystemError($errstr); 
     98                exit(1); 
     99                break; 
     100 
     101            case E_WARNING: 
     102            case E_USER_WARNING: 
     103            case E_CORE_WARNING: 
     104            case E_COMPILE_WARNING: 
     105                $message = $now . " [$errfile:$errline] WARNING($errno) $errstr from ". $_SERVER['REMOTE_ADDR'] . "\n"; 
     106                error_log($message, 3, $log_file_path); 
     107                return true; 
     108                break; 
     109 
     110            default: 
     111        } 
     112    } 
     113 
     114    /** 
     115     * エラーを捕捉するための関数. (for PHP < 5.2.0) 
     116     * 
     117     * PHP4 では, try/catch が使用できず, かつ set_error_handler で Fatal Error は 
     118     * 捕捉できないため, ob_start にこの関数を定義し, Fatal Error が発生した場合 
     119     * に出力される HTML 出力を捕捉する. 
     120     * この関数が実行され, エラーが捕捉されると, DEBUG_MODE が無効な場合, 
     121     * エラーページへリダイレクトする. 
     122     * 
     123     * @param string $buffer 出力バッファリングの内容 
     124     * @return string|void エラーが捕捉された場合は, エラーページへリダイレクトする; 
     125     *                     エラーが捕捉されない場合は, 出力バッファリングの内容を返す 
     126     */ 
     127    static function &_fatal_error_handler(&$buffer) { 
     128        if (preg_match('/<b>(Fatal) error<\/b>: +(.+) in <b>(.+)<\/b> on line <b>(\d+)<\/b><br \/>/i', $buffer, $matches)) { 
     129            $now = date("Y/m/d H:i:s"); 
     130            // 本来 realpath() で正規化したいところだが、NULL を返すケースがあるため避けている (#1618) 
     131            $log_file_path = DATA_REALDIR . 'logs/site.log'; 
     132            $message = $now . " [$matches[3]:$matches[4]] FATAL Error: $matches[2] from ". $_SERVER['REMOTE_ADDR'] . "\n"; 
     133            error_log($message, 3, $log_file_path); 
     134            if (DEBUG_MODE !== true) { 
     135                $url = HTTP_URL . "error.php"; 
     136                if (defined('ADMIN_FUNCTION') && ADMIN_FUNCTION) { 
     137                    $url .= "?admin"; 
     138                } 
     139                header("Location: $url"); 
     140                exit; 
     141            } 
     142        } 
     143        return $buffer; 
     144    } 
     145 
     146    /** 
     147     * エラー捕捉時のエラーハンドラ関数 (for PHP >= 5.2.0) 
     148     * 
     149     * この関数は, register_shutdown_function() 関数に登録するための関数である。 
     150     * PHP 5.1 対応処理との互換運用ため E_USER_ERROR は handle_warning で捕捉する。 
     151     * 
     152     * @return void 
     153     */ 
     154    static function handle_error() { 
     155        // 最後のエラーを確実に捉えるため、先頭で呼び出す。 
     156        $arrError = error_get_last(); 
     157 
     158        $is_error = false; 
     159        if (isset($arrError)) { 
     160             switch ($arrError['type']) { 
     161                 case E_ERROR: 
     162                 case E_PARSE: 
     163                 case E_CORE_ERROR: 
     164                 case E_COMPILE_ERROR: 
     165                      $is_error = true; 
     166                 break; 
     167             } 
     168        } 
     169 
     170        if (!$is_error) { 
     171            return; 
     172        } 
     173 
     174        $errstr = "[{$arrError[file]}:{$arrError[line]}] FATAL Error({$arrError[type]}) {$arrError[message]}"; 
     175 
     176        // ログの書き出し 
     177        $now = date("Y/m/d H:i:s"); 
     178        // 本来 realpath() で正規化したいところだが、NULL を返すケースがあるため避けている (#1618) 
     179        $log_file_path = DATA_REALDIR . 'logs/site.log'; 
     180        error_log($now . " $errstr from ". $_SERVER['REMOTE_ADDR'] . "\n", 3, $log_file_path); 
     181 
     182        // エラー画面を表示する 
     183        self::displaySystemError($errstr); 
     184    } 
     185 
     186    /** 
     187     * エラー画面を表示する 
     188     * 
     189     * @param string|null $errstr エラーメッセージ 
     190     * @return void 
     191     */ 
     192    static function displaySystemError($errstr = null) { 
     193        ob_clean(); 
     194 
     195        // 絵文字変換・除去フィルターが有効か評価する。 
     196        $loaded_ob_emoji = false; 
     197        $arrObs = ob_get_status(true); 
     198        foreach ($arrObs as $arrOb) { 
     199            if ($arrOb['name'] === 'SC_MobileEmoji::handler') { 
     200                $loaded_ob_emoji = true; 
     201                break; 
     202            } 
     203        } 
     204 
     205        // 絵文字変換・除去フィルターが無効で、利用できる場合、有効にする。 
     206        if (!$loaded_ob_emoji && class_exists('SC_MobileEmoji')) { 
     207            ob_start(array('SC_MobileEmoji', 'handler')); 
     208        } 
     209 
     210        require_once CLASS_EX_REALDIR . 'page_extends/error/LC_Page_Error_SystemError_Ex.php'; 
     211        $objPage = new LC_Page_Error_SystemError_Ex(); 
     212        register_shutdown_function(array($objPage, 'destroy')); 
     213        $objPage->init(); 
     214        if (isset($errstr)) { 
     215            $objPage->arrDebugMsg[] 
     216                = "▼▼▼ エラーメッセージ ▼▼▼\n" 
     217                . $errstr . "\n" 
     218                . "▲▲▲ エラーメッセージ ▲▲▲\n" 
     219            ; 
     220        } 
     221        $objPage->process(); 
     222    } 
    28223} 
    29  
    30 // エラーレベル設定 
    31 // 開発時は E_ALL を推奨 
    32 error_reporting(E_ALL & ~E_NOTICE & ~E_USER_NOTICE & ~E_DEPRECATED); 
    33  
    34 if (!defined('SAFE') || SAFE !== true || !defined('INSTALL_FUNCTION') || INSTALL_FUNCTION !== true) { 
    35     // エラー捕捉用の出力バッファリング 
    36     ob_start('_fatal_error_handler'); 
    37  
    38     // E_USER_ERROR を捕捉した場合にエラー画面を表示させるためのエラーハンドラ 
    39     set_error_handler('handle_error', error_reporting()); 
    40 } 
    41  
    42 /** 
    43  * エラーを捕捉するための関数. 
    44  * 
    45  * PHP4 では, try/catch が使用できず, かつ set_error_handler で Fatal Error は 
    46  * 捕捉できないため, ob_start にこの関数を定義し, Fatal Error が発生した場合 
    47  * に出力される HTML 出力を捕捉する. 
    48  * この関数が実行され, エラーが捕捉されると, DEBUG_MODE が無効な場合, 
    49  * エラーページへリダイレクトする. 
    50  * 
    51  * @param string $buffer 出力バッファリングの内容 
    52  * @return string|void エラーが捕捉された場合は, エラーページへリダイレクトする; 
    53  *                     エラーが捕捉されない場合は, 出力バッファリングの内容を返す 
    54  */ 
    55 function &_fatal_error_handler(&$buffer) { 
    56     if (preg_match('/<b>(Fatal) error<\/b>: +(.+) in <b>(.+)<\/b> on line <b>(\d+)<\/b><br \/>/i', $buffer, $matches)) { 
    57         $now = date("Y/m/d H:i:s"); 
    58         error_log($now . " [$matches[3]:$matches[4]] FATAL Error: $matches[2] from ". $_SERVER['REMOTE_ADDR'] . "\n", 3, 
    59                   realpath(dirname(__FILE__) . "/" . HTML2DATA_DIR . "logs/site.log")); 
    60         if (DEBUG_MODE !== true) { 
    61             $url = HTTP_URL . "error.php"; 
    62             if (defined('ADMIN_FUNCTION') && ADMIN_FUNCTION) { 
    63                 $url .= "?admin"; 
    64             } 
    65             header("Location: $url"); 
    66             exit; 
    67         } 
    68     } 
    69     return $buffer; 
    70 } 
    71  
    72 /** 
    73  * E_USER_ERROR を捕捉した場合にエラー画面を表示させるエラーハンドラ関数. 
    74  * 
    75  * この関数は, set_error_handler() 関数に登録するための関数である. 
    76  * trigger_error にて E_USER_ERROR が生成されると, エラーログを出力した後, 
    77  * エラー画面を表示させる. 
    78  * E_WARNING, E_USER_WARNING が発生した場合、ログを記録して、true を返す。 
    79  * (エラー画面・エラー文言は表示させない。) 
    80  * 
    81  * @param integer $errno エラーコード 
    82  * @param string $errstr エラーメッセージ 
    83  * @param string $errfile エラーが発生したファイル名 
    84  * @param integer $errline エラーが発生した行番号 
    85  * @return void|boolean E_USER_ERROR が発生した場合は, エラーページへリダイレクト; 
    86  *                      E_WARNING, E_USER_WARNING が発生した場合、true を返す 
    87  */ 
    88 function handle_error($errno, $errstr, $errfile, $errline) { 
    89  
    90     // error_reporting 設定に含まれていないエラーコードは処理しない 
    91     if (!(error_reporting() & $errno)) { 
    92         return; 
    93     } 
    94  
    95     $now = date("Y/m/d H:i:s"); 
    96     // 本来 realpath() で正規化したいところだが、NULL を返すケースがあるため避けている (#1618) 
    97     $log_file_path = dirname(__FILE__) . '/' . HTML2DATA_DIR . 'logs/site.log'; 
    98     switch ($errno) { 
    99         case E_USER_ERROR: 
    100             error_log($now . " [$errfile] FATAL Error($errno) $errfile:$errline $errstr from ". $_SERVER['REMOTE_ADDR'] . "\n", 3, $log_file_path); 
    101  
    102             displaySystemError($errstr); 
    103             exit(1); 
    104             break; 
    105  
    106         case E_WARNING: 
    107         case E_USER_WARNING: 
    108             error_log($now . " [$errfile] WARNING($errno) $errfile:$errline $errstr from ". $_SERVER['REMOTE_ADDR'] . "\n", 3, $log_file_path); 
    109             return true; 
    110             break; 
    111  
    112         default: 
    113     } 
    114 } 
    115  
    116 /** 
    117  * エラー画面を表示する 
    118  * 
    119  * @param string|null $errstr エラーメッセージ 
    120  * @return void 
    121  */ 
    122 function displaySystemError($errstr = null) { 
    123     if (SC_Display_Ex::detectDevice() == DEVICE_TYPE_MOBILE) { 
    124         ob_clean(); 
    125         ob_start(array('SC_MobileEmoji', 'handler')); 
    126     } else { 
    127         // 最下層以外の出力用バッファをクリアし、出力のバッファリングを解除する 
    128         // FIXME #811(出力バッファリングの利用を見直し) 
    129         while (ob_get_level() >= 2) { 
    130             ob_end_clean(); 
    131         } 
    132  
    133         // 最下層の出力バッファをクリアする 
    134         ob_clean(); 
    135     } 
    136  
    137     require_once CLASS_EX_REALDIR . 'page_extends/error/LC_Page_Error_SystemError_Ex.php'; 
    138     $objPage = new LC_Page_Error_SystemError_Ex(); 
    139     register_shutdown_function(array($objPage, 'destroy')); 
    140     $objPage->init(); 
    141     if (isset($errstr)) { 
    142         $objPage->arrDebugMsg[] 
    143             = "▼▼▼ エラーメッセージ ▼▼▼\n" 
    144             . $errstr 
    145             . "▲▲▲ エラーメッセージ ▲▲▲\n" 
    146         ; 
    147     } 
    148     $objPage->process(); 
    149 } 
  • branches/version-2_12-dev/data/class/helper/SC_Helper_Mobile.php

    r21442 r21465  
    232232        mb_http_output('SJIS-win'); 
    233233 
    234         // 絵文字タグを絵文字コードに変換する。 
    235         ob_start(array('SC_MobileEmoji_Ex', 'handler')); 
    236  
    237234        // 端末に合わせて画像サイズを変換する。 
    238235        ob_start(array('SC_MobileImage_Ex', 'handler')); 
  • branches/version-2_12-dev/html/admin/require.php

    r21420 r21465  
    2727 
    2828require_once HTML_REALDIR . 'define.php'; 
    29 require_once HTML_REALDIR . 'handle_error.php'; 
    30  
     29while (@ob_end_flush()); 
    3130require_once HTML_REALDIR . HTML2DATA_DIR . 'require_base.php'; 
    32  
    3331ob_start(); 
  • branches/version-2_12-dev/html/install/index.php

    r21445 r21465  
    2828define('INSTALL_FUNCTION', true); 
    2929define("INSTALL_INFO_URL", "http://www.ec-cube.net/install_info/index.php"); 
    30 require_once HTML_REALDIR . 'handle_error.php'; 
     30while (@ob_end_flush()); 
    3131require_once HTML_REALDIR . HTML2DATA_DIR . 'require_base.php'; 
     32ob_start(); 
    3233// ▲require.php 相当 
    3334 
  • branches/version-2_12-dev/html/require.php

    r21464 r21465  
    3030 
    3131require_once HTML_REALDIR . 'define.php'; 
    32 require_once HTML_REALDIR . 'handle_error.php'; 
     32while (@ob_end_flush()); 
    3333require_once HTML_REALDIR . HTML2DATA_DIR . 'require_base.php'; 
     34 
     35// 絵文字変換 (除去) フィルターを組み込む。 
     36ob_start(array('SC_MobileEmoji', 'handler')); 
    3437 
    3538if (SC_Display_Ex::detectDevice() == DEVICE_TYPE_MOBILE) { 
    3639    $objMobile = new SC_Helper_Mobile_Ex(); 
    3740    $objMobile->sfMobileInit(); 
    38     ob_start(); 
    39 } else { 
    40     // 絵文字変換 (除去) フィルターを組み込む。 
    41     ob_start(array('SC_MobileEmoji', 'handler')); 
    4241} 
Note: See TracChangeset for help on using the changeset viewer.