![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Przyjaciele php.pl Postów: 195 Pomógł: 0 Dołączył: 7.07.2003 Skąd: Warszawa Ostrzeżenie: (0%) ![]() ![]() |
Witam.
Jak mozna wyczytac z tytulu zastanawiam sie nad optymalnym rozwiazaniem oblugi bledow w CMSie. (mowa o php 4 - no exceptions) Obsluga bledow sklada sie z dwoch podelementow: 1) Obsluga bledow skladni - zglaszanych przez silnik php i przechwytywanych przez error_handler 2) Obsluga bledow logicznych i algorytmicznych, niewykrywalnych dla php. Zglaszanych z poziomu kodu. Martwia mnie obydwa problemu, ale z roznych wzgledow. Pierwszy, dlatego, ze php zglasza szalenie mala ilosc informacji o bledzie (np. nie ma mozliwosci uzyskania inforamcji o linii w ktorej nastapil blad!!!). Drugi, z powodu (tak podejrzewam) malego doswiadcznia z tematem. Na poczatku nie wiedzialem wogule jak podejsc do tematu i lazilem wokol niego jak pies wokol jeza. W koncu sprecyzowalem zalozenia obslugi bledow. Musi obslugiwac jak najwiekszy zakres bledow, kontrolowac stabilnosc aplikacji, obslugiwac "tranzakcje" (*1) oraz w jak najlatwiejszy sposob integrowac sie z CMSem (*2). *1) chodzi o system podobny do uzywanego w bazach danych. Jesli kawalek kodu ma wykonac logiczna operacje "dodania konta" ktora sklada sie z dodania wpisu do tablicy |accounts|, dodania wpisu do tablicy |account_privs| oraz dodania dwoch katalogow (zalozmy!!) to fajnie by bylo, moc to latwo wycofac jest cokolwiek pojdzie nie tak. *2) Innymi slowy, aby latwo i czysto wygladalo w CMSie wybor czy wyswietlac dalej skrypt czy juz komunikat o bledzie. Wstepnie zaprojektowalem cos w tym stylu: [php:1:f44bd586cd]<?php <?php /************************************************** * * Error Class. Handling errors * *************************************************** * * No table related. * *************************************************** * * Detail description * @author Zbigniew Braniecki (gandalf@przeglad.com.pl) * @version 1.0 M1 * @copyright Zbigniew Braniecki * @access private * @relase_date 08.10.2002 * *************************************************** * * Short Description * * Variables: * errorlevel - Describes status of system. * Possible codes are: * 0 - no error * 1 - notice error - something might be wrong, but it miht be ok too * 2 - warning error - something is wrong, but script works * 3 - rollback error - error in setting data. should be rolled back and warned * 4 - security error - there was a try of illegal access * 5 - fatal error - module wont work. * 6 - gcms error - gcms wont run * * errors - Array of errors code with modules name and description. * "code" - Code number * "trasaction" - which transaction was active? * "module" - Module name * "action" - Action * "description" - Description * * Methods: * * SetErrorLevel($level,$force=false) * $force - if set (boolean) New errorlevel is forced even if the old one was higher. * * AddError($lvl,$module,$desc) * Adds error to array of errors * * AddToErrFile($module,$desc,$rubbish) * $rubbish - if there can by any parts (sql rows or files) to clean up, write them down here. * Adds error to error file. * * RunCapture() * System captures php errors and log them. * *************************************************** * * Known bugs and problems * *************************************************** * * Notes * ***************************************************/ class ErrorClass { var $errorlevel = 0; var $errors = Array('cms'=>Array(), 'code'=>Array()); var $debug_mode = true; var $security = false; var $php_errcode = Array(1=>6, 2=>5, 4=>6, 8=>1, 16=>6, 32=>5, 64=>6, 128=>5, 256=>5, 512=>5, 1024=>1, 2056=>-1); var $transactions = Array(); function SetErrorlevel ($level, $force=false) { if (($level>$this->errorlevel) || $force) { $this->errorlevel = $level; } return true; } function CreateTransaction ($name) { $this->transactions[] = Array('name' => $name, 'rollback' => Array(), 'errors'=> false); return key($this->transactions); } function FinishTransaction ($id) { unset($this->transactions[$id]); return true; } function Rollback ($tr_id, $module, $method, $argList) { $this->transactions[$tr_id]['rollback'][] = Array('module'=>$module, 'method'=>$method, 'arglist'=>$argList); return true; } function AddError ($lvl, $module, $action, $desc, $tr_id=false, $type='cms') { $GLOBALS['system']->reload = false; $this->SetErrorlevel($lvl); switch ($lvl) { case 0: $code=$GLOBALS['sysdict']['error_no_error']; break; case 1: $code=$GLOBALS['sysdict']['error_notice']; break; case 2: $code=$GLOBALS['sysdict']['error_warning']; break; case 3: $code=$GLOBALS['sysdict']['error_rollback']; break; case 4: $code=$GLOBALS['sysdict']['error_security']; break; case 5: $code=$GLOBALS['sysdict']['error_major']; break; case 6: $code=$GLOBALS['sysdict']['error_blow']; break; default: $code=$GLOBALS['sysdict']['error_unknown']; } if ($tr_id === false) { if (isset($this->transactions[key($this->transactions)])) { $tr_name = $this->transactions[key($this->transactions)]['name']; $this->transactions[key($this->transactions)]['errors'] = true; $tr_id = key($this->transactions); } else { $tr_name = '--'; } }elseif ($tr_id !== '--') { if (isset($this->transactions[$tr_id])) { $tr_name = $this->transactions[$tr_id]['name']; $this->transactions[$tr_id]['errors'] = true; }else{ $tr_name = '--'; } } $this->errors[$type][] = Array('code'=>$code, 'transaction' => $tr_name,'module'=>$module, 'action'=>$action, 'description'=>$desc); $this->AddToErrFile ($code, $module, $action, $desc); foreach ($this->transactions as $t) { foreach ($t['rollback'] as $e) { eval('$GLOBALS["'.$e['module'].'"]->'.$e['method'].'('.implode($e['arglist'], ',').');'); } } if ($type=='code') { print('<br>'.$GLOBALS['sysdict']['error_code'].': '); print_r(current($this->errors[$type])); die($GLOBALS['sysdict']['stop']); } return true; } function AddToErrFile ($lvl, $module, $action, $desc) { $fh=fopen('../admin/error.log','a'); fputs($fh,date('[d-m-Y H:i]').' '.$GLOBALS['sysdict']['error'].' ('.$lvl.') '.$GLOBALS['sysdict']['in_module'].' - '.$module.' '.$GLOBALS['sysdict']['in_action'].' - '.$action.' - '.$desc."n"); fclose($fh); } function RunCapture(){ function ErrorHandler ($errno, $errstr, $errfile, $errline, $errcontexa) { global $error; $error->SetErrorlevel($error->php_errcode[$errno]); $error->AddError($error->php_errcode[$errno], ' - ', ' - ', $GLOBALS['sysdict']['in_file'].' '.$errfile.', '.$GLOBALS['sysdict']['in_line'].' '.$errline, false, $GLOBALS['sysdict']['code']); } set_error_handler('ErrorHandler'); return true; } // DONE - 08.10.2002 /////////////////////////////////////////////////////// } ?> ?>[/php:1:f44bd586cd] (sysdict to slownik CMSa) uzycie: [php:1:f44bd586cd]<?php $tr_id = $errors->CreateTransaction('Adding Account'); if (!mysql_query($q_tmp)) { $errors->AddError(3, 'Account', 'Adding Account', 'Account was not added due too Mysql Error nr. '.mysql_errno().' - '.mysql_error(), $tr_id); return false; } $curr_id = mysql_insert_id(); $errors->Rollback($tr_id, 'account', 'Remove', Array($curr_id)); // For both if (!$access->SetPrivileges($curr_id)) { $errors->AddError(3, 'Account', 'Adding Account', 'Setting Privilages failed', $tr_id); return false; } $errors->FinishTransaction($tr_id); ?>[/php:1:f44bd586cd] Czyli na ludzki: 1) Rozpocznij tranzakcje 2) Dodaj konto do bazy - jesli sie nie powiedzie zwroc blad (tranzakcja zostanie zatrzymana, ale nie cofnieta - brak Rollbacka) 3) Dodaj rollback 4) dodac uprawnienia - jesli padnie tranzakcja zostanie cofnieta i rollback uruchomiony . . tutaj mozna dodawac kolejne elementy . n) Zakoncz tranzakcje. Moj problem jest prosty. Chcialbym Was prosic o pomoc w udoskonaleniu tego, oczyszczeniu... bo napisalem to pewien czas temu i do dzis nie mam pomyslu jak to usprawnic. Mam ogromna nadzieje, ze swierze spojrzenie na problem waszych oczu popchnie cala sprawe do przodu. ![]() Bede wdzieczny za kazda sugestie ![]() P.S. Zastanawialem sie czy to nie do Oceny, ale zamiast oceny wolalbym teoretyczna chocby dyskusje o samych zalozeniach takiego errorHandlera... moze ja wogule w zla strone ide? |
|
|
![]() ![]() |
![]() |
Aktualny czas: 21.08.2025 - 16:08 |