2017-02-20 51 views
7

TLDR: Czy ktoś wie o konkretnych przypadkach, oprócz pokazanego poniżej, gdzie PDO::exec(), PDO::query(), PDO::prepare() lub PDOStatement::execute() może return false bez wyjątku są rzucone, mimo PDO::ATTR_ERRMODE jest ustawiony na PDO::ERRMODE_EXCEPTION?PHP PDO w trybie wyjątku - nadal trzeba sprawdzić powrót funkcji wykonywania (i inne)?

Próbuję zdecydować, czy chcę dodać sprawdzanie pod kątem fałszywości do każdego zapytania bazy danych, które napiszę, lub czy jest to zbędne.

Edytuj: Obecnie używam wyłącznie MySQL, ale jeśli przenośność jest czynnikiem, może to być wystarczające, aby oprzeć decyzję. Używam PDO::ATTR_EMULATE_PREPARES => FALSE, jeśli to ma znaczenie.


Oto konkretny przypadek, o którym wspomniałem. Jeśli przygotujesz instrukcję z co najmniej 0 symbolami zastępczymi (dowolnego typu), a następnie podasz tablicę argumentów dla PDOStatement::execute() z większą liczbą elementów niż są elementy zastępcze, zwracana jest false bez zgłaszania wyjątku. Zwróć uwagę, że wykonanie powiedzie się (i tylko dodatkowe wiązanie się nie powiedzie), jeśli zamiast tego zostanie użyty PDOStatement::bindValue(). Używanie mniejszej liczby parametrów niż symbole zastępcze powoduje zgłoszenie wyjątku, niezależnie od tego, czy parametry zostały przekazane do funkcji execute za pośrednictwem tablicy, czy też zostały powiązane przy użyciu metody PDOStatement::bindValue()//.

// Execute returns false, no exception thrown 
$so = $rh->pdo->prepare("SELECT * FROM config"); 
if($so->execute(['Test']) === FALSE) echo '1. False returned <br />'; 

// Execute does not return false, no exception thrown 
$so = $rh->pdo->prepare("SELECT * FROM config"); 
if($so->bindValue(1, 'Test') === FALSE) echo '2. Binding failed <br />'; 
if($so->execute() === FALSE) echo '2. False not returned <br />'; 

// Execute returns false, no exception thrown 
$so = $rh->pdo->prepare("SELECT * FROM config WHERE webmaster_name = ?"); 
if($so->execute(['Test', 'Wee']) === FALSE) echo '3. False returned <br />';  

// Execute does not return false, no exception thrown 
$so = $rh->pdo->prepare("SELECT * FROM config WHERE webmaster_name = ?"); 
$so->bindValue(1, 'Test'); 
if($so->bindValue(2, 'Wee') === FALSE) echo '4. Binding failed <br />'; 
if($so->execute() === FALSE) echo '4. False not returned <br />'; 

Outputs: 
1. False returned 
2. Binding failed 
3. False returned 
4. Binding failed 

Na select, to nie jest szczególnie niebezpieczne w tym przypadku polegać na wyjątkami, jak błąd będzie występować w każdym razie jeśli próbował wywołać metodę sprowadzania na FALSE zamiast PDOStatement obiektu. Ale są zapytania, takie jak INSERTS lub AKTUALIZACJE, które mogą po cichu zawieść, jeśli nie zrobisz fałszywego czeku.


Nauczyłem się PDO i staram się decydować o ogólnej praktyce obsługi błędów w przyszłości.

Zdecydowanie preferuję wyjątki, ponieważ mam już dobry przewodnik po witrynie, który można skonfigurować dla różnych scenariuszy. I wydaje się, że używanie wyjątków będzie oznaczać mniej pisanie, ponieważ nie musisz wyraźnie sprawdzać zwrotów wielu funkcji PDO.

CZY MASZ? (dźwiękowa muzyka dramatyczna)

Kiedy czytałem, natknąłem się na więcej niż jedną wzmiankę o funkcjach PDO (a nie odbierającej odmianie), która zwróciła fałszywe wyniki bez wyjątku.

Moje pytanie brzmi, czy uważa się za najlepszą praktykę sprawdzanie zwrotu tych funkcji, czy też większość ludzi uważa tę przesadę.

Widziałem wiele sprzecznych oświadczeń na temat SO. Po jednej stronie widziałem liczne stwierdzenia: "Wyjątki PDO są wiarygodne"; "Wyjątki PDO będą zawsze generowane, gdy FALSE zostanie zwrócona" (wznowione przez ludzi mówiących "Myślę, że to prawda").

Oto kilka komentarzy, które prowadzą mnie do zastanowienia, chociaż nie widziałem jeszcze konkretnego przykładu poza tym, o którym wspomniałem.


Od Can PDO methods fail and not throw PDOException?:

I nie wydaje się replikować ten scenariusz od kilku przypadków testowych (mam tryb emulacji off).

  1. „(Vincent Ryan), gdy jest fałszywe i emuluje ... typy wiążące są błędne. To nie może rzucić wyjątek czasami”.

Ten wydaje się być kwestionowany? Nie jestem pewien, jak to przetestować.

  1. „(Xorifelse) Teraz za popełnienie na niepowodzenie, wierzę, że istnieje 1 scenariusz, który powoduje zwrócenie false bez rzuca wyjątek i to jest, gdy połączenie z serwer po podłączeniu do bazy danych i przed wywołaniem PDO::commit, całkiem niezły wiedzieć, czy masz zdalny serwer bazy danych.Tak więc, aby odpowiedzieć na twoje pytanie, tak może się nie udać bez wyjątku, ale jego czas musi być bardzo specyficzny, jeszcze bardziej jeśli masz lokalną bazę danych. "

Od will a false returned PDO execute() the same as the exception it thrown?:

Jest to jedyny możliwy scenariusz mam natknąć się, że byłem w stanie odtworzyć (patrz wyżej).

  1. „(Niksac) Widziałem execute() powracającego false bez rzuca wyjątek, który jest swego rodzaju nieoczekiwane/złe zachowanie w mojej opinii. Oznacza to, że w zasadzie trzeba zrobić zarówno - obsługa błędów i wyjątków równolegle, w moim przypadku: jeśli przygotowałem kwerendę wstawiania bez żadnych parametrów, a następnie wykonałem ją parametrem, Execute nie wyrzuci wyjątku, ale zwróci false. "

Z Should I check the return value of an execute operation in pdo php:

  1. "(castis) $stmt->execute() można całkowicie powrót false nie rzucając wyjątek"

Chyba znalazłem co najmniej jeden inny nieswoiste wzmianki przy czym możliwe (false zwracana, bez wyjątku), choć nie mogę śledzić je ponownie w dół.


Przeglądanie samouczków PDO w Internecie, większość z nich nie sprawdza zwrotów, gdy używany jest tryb wyjątków. Ale spotkałem kilka osób, które go polecają.

Opisany przeze mnie przypadek nie jest czymś, co prawdopodobnie zepsuję w codziennym użytkowaniu. Albo jeśli to zrobię, powinienem się natychmiast dowiedzieć. I jeśli kiedykolwiek dynamicznie budowałbym liczbę elementów zastępczych lub parametrów w zapytaniu, wiedziałbym, żeby upewnić się, że liczba pasuje i/lub sprawdzić fałsz w tym jednym przypadku.

Po prostu nie chcę sprawdzać zwrotu każdego użycia polecenia execute, zapytania itp., Jeśli nie jest to konieczne.Jeśli przykład wspomniałem jest to jedyny znany przypadek, czułbym się bezpiecznie pozostawiając fałszywą wymeldować z większości zapytań, który pozwoliłby mi zrobić więcej metoda łańcuchowym:

$user_info = $rh->pdo->query("SELECT * FROM users WHERE user_id = 1")->fetch(); 

// vs 

$so = $rh->pdo->query("SELECT * FROM users WHERE user_id = 1"); 
if($so === FALSE) // Throw an exception 
$user_info = $so->fetch(); 

Chyba co szukam jest pewne wsparcie od bardziej doświadczonych programistów, że można ominąć ten czek tak, jak widzę, że ludzie to robią. Albo to, albo ludzie mówiący mi, jak zostali spaleni przez ominięcie tego czeku.

+0

chodzi ATTR_EMULATE_PREPARES - Widziałem zachowanie gdzie PDO nie wyjątek jeśli podasz params z oświadczeniem to nie powinno mieć żadnego. Przypominam, że udało mi się zweryfikować ten problem u innego użytkownika w zeszłym tygodniu. Nie wiem, czy to robi różnicę, aby jawnie "bindParam()" vs przekazać tablicę do 'execute()' jak w przykładzie zwracania fałszywych odpowiedzi, ale zdecydowanie widziałem, że PDO nie wyrzuca wyjątku z niepoprawna tablica parametrów. –

+0

Wiele z tych zachowań zależy od podstawowego sterownika DBMS. CHNP stara się standaryzować rzeczy tak często, jak to możliwe, ale wciąż istnieją odmiany. Jakiej bazy danych używasz? MySQL, SQL Server, itp? –

+0

Dzięki za odpowiedzi facetów. Wyłącznie MySQL w tej chwili. W najbliższym czasie nie widzę siebie korzystającego z innej bazy danych. Ale jeśli istnieją potencjalne okazje tylko z innymi bazami danych, do których może kiedyś chciałbym się przyłączyć (lub zmusić do pracy), to nadal może być czynnik. Myślę, że jeśli przenośność jest problemem w tym przypadku, to może to wystarczyć do oparcia decyzji. – dnag

Odpowiedz

1

Istnieją zdecydowanie różne Gotchas w zależności od używanej bazy danych. Jeśli przenośność jest problemem, nie polegałbym na pewnych cechach MySQL, które, jak się wydaje, znajdują się powyżej.

Na przykład, nie są takie:

+0

Dzięki za odpowiedź. Nie otrzymałem wiele zaufania w odpowiedziach, że można ominąć fałszywe kontrole. Na razie nie mam nic przeciwko bezpiecznej stronie i zawsze sprawdzam, mimo że nie widziałem jeszcze innego szczególnego przypadku, w którym wyjątek nie zostanie zgłoszony i zwrócone zostanie false. Wyłączam emulowane przygotowanie, jeśli to ma znaczenie. – dnag