Używam Zend_Db_Adapter
, a konkretnie Zend_Db_Adapter_Pdo_Abstract
. Wyobrażam sobie, że ten problem dotyczy również innych adapterów. Kiedy PDOException
jest rzucany, jest „nieprzechwycony”, aw wielu przypadkach ślad stosu ujawnia nazwę użytkownika i hasło.
Sprawdziłem, że wszystkie następujące wyjątki PDO pokazują poświadczenia w śladzie stosu:
- SQLSTATE[HY000] [2005] Nieznany host serwera MySQL ...snip...
- SQLSTATE[HY000] [2013] Utracono połączenie z serwerem MySQL podczas „odczytu pakietu autoryzacyjnego”
- SQLSTATE[08004] [1040] Za dużo połączeń
- SQLSTATE[28000] [1045] Odmowa dostępu dla użytkownika ...snip... (przy użyciu hasła: YES)
Moje witryny produkcyjne nie wyświetlają śladów stosu, gdy występują błędy, i nadal chcę widzieć ślady stosu dla tych błędów w moich środowiskach programistycznych. Po prostu nie chcę, aby nazwy użytkowników i hasła były wyświetlane w sposób przejrzysty.
2 odpowiedzi
Rozwiążę to, nie rozwiązując tego... Pozwólcie, że wyjaśnię:
Obecnie nie ma możliwości wyłączenia śledzenia stosu z nieprzechwyconych wyjątków. PHP Ci na to nie pozwala.
Więc zamiast próbować go wyłączyć, po prostu nie pozwoliłbym, aby wyjątek pozostał niezauważony... Zainstalowałbym obsługa wyjątków, który następnie loguje informacje o śladach wstecznych. Nie wyświetlałbym tego na ekranie. Nie sprawdzałbym, w jakim środowisku się znajduje. Nie sprawdzałbym informacji o żądaniu. Po prostu zalogowałbym go do pliku i wyświetlił ogólną stronę błędu serwera 500.
Teraz w swoim module obsługi możesz selektywnie wyświetlać informacje o wywołaniu, dzięki czemu możesz wybrać, czy chcesz rejestrować informacje o argumencie:
set_exception_handler(function($exception) {
$log = array(
'message' => $exception->getMessage(),
'trace' => array(),
);
foreach ($exception->getTrace() as $item) {
$trace = isset($item['class']) ? $item['class'] . $item['type'] : '';
$trace .= $item['function'] . '()';
$log['trace'][] = $trace;
}
save_to_log($log);
});
Ale traktuję niewyłapany wyjątek jako znak błędu w twojej aplikacji. Powinieneś je znaleźć i naprawić. Jeśli zdobędziesz je na tyle, że martwisz się o przedstawienie argumentów na stronie, to naprawdę musisz naprawić fakt, że istnieją nieprzechwycone wyjątki w pierwszej kolejności...
Edytuj Oto demonstracja tego, co się dzieje:
class Foo {
public function doSomething($user, $password) {
throw new Exception('Something Went Wrong!');
}
}
$f = new Foo();
$f->doSomething('user', 'passw');
Wyniki w CodePadzie:
<br />
<b>Fatal error</b>: Uncaught exception 'Exception' with message 'Something Went Wrong!' in /code/MxH9Ls:4
Stack trace:
#0 /code/MxH9Ls(10): Foo->doSomething('user', 'passw')
#1 {main}
thrown in <b>/code/MxH9Ls</b> on line <b>4</b><br />
Ale z obsługą wyjątków (zmodyfikowaną do drukowania zamiast dziennika):
set_exception_handler(function($exception) {
$log = array(
'message' => $exception->getMessage(),
'trace' => array(),
);
foreach ($exception->getTrace() as $item) {
$trace = isset($item['class']) ? $item['class'] . $item['type'] : '';
$trace .= $item['function'] . '()';
$log['trace'][] = $trace;
}
echo $log['message'] . "\n";
foreach ($log['trace'] as $trace) {
echo " - $trace\n";
}
});
class Foo {
public function doSomething($user, $password) {
throw new Exception('Something Went Wrong!');
}
}
$f = new Foo();
$f->doSomething('user', 'passw');
W CodePad generuje:
Something Went Wrong!
- Foo->doSomething()
Można spróbować dwóch rzeczy, pierwszym i prawdopodobnie najlepszym rozwiązaniem byłoby przechwycenie wyjątków i przekazanie ich do niestandardowej klasy wyjątków. Klasa brałaby również instancję adaptera na wzór:
Nieprzetestowany przykład
class myPDOException extends Exception
{
public function __construct($message = '', $code = 0, Exception $previous = null, Zend_Db_Adapter_Abstract $adapter) {
$config = $adapter->getConfig();
$message = str_replace(array($config['username'], $config['password']), array('--user--', '--pass--'));
parent::__construct($message, $code, $previous);
}
}
Inną opcją byłoby użycie set_exception_handler po sprawdzeniu w swoim programie początkowym, czy środowisko jest programistyczne, wtedy możesz wykonać następujące czynności;
function exception_handler($exception) {
if ($exception instanceof PDOException) {
//load your configuration
//replace the user pass in the message
//rethrow the exceptio with the updated message
}
}
set_exception_handler('exception_handler');
Sposób, w jaki radzę sobie z nieprzewidzianymi wyjątkami, polega na zapisaniu ich w kolejce, która następnie prześle mi wszystkie niezbędne informacje i możemy naprawić przyczynę wyjątku.
Mam nadzieję, że to pomoże
Sójka
Podobne pytania
Nowe pytania
php
PHP to szeroko stosowany, wysokopoziomowy, dynamiczny, zorientowany obiektowo i interpretowany język skryptowy przeznaczony głównie do tworzenia stron WWW po stronie serwera. Używane w przypadku pytań dotyczących języka PHP.