Hei!
Voisitteko selventää hieman minulle mikä tuon try:n sekä catch:in tarkoitus tuossa on.
Ensiksi yritetään (try) luoda yhteys tietokantaan "testit". Jos tämä ei onnistu, niin PDO heittää (throw) poikkeuksen (exception). Poikkeus pitää ottaa kiinni catch-lohkossa. PDOException on poikkeuksen tyyppi, joka halutaan ottaa kiinni.
Yksinkertaisesti tarkoitus on siis lopettaa koodin ajo ja tulostaa virheilmoitus, jos tietokantaan ei saada yhteyttä.
PHP.net:stä löytyy tietoa poikkeuksista. PDO:n heittämistä poikkeuksista lisää.
Käytännössä kyseisessä tapauksessa yritetään muodostaa yhteyttä tietokantaan ja jos yhdistys epäonnistuu PDO heittää (throw) poikkeuksen joka napataan catch:illä ja siirrytään siis suoraan tuohon catch lohkoon, eikä muuta koodia enää suoriteta try-lohkon sisällä. Catch-lohkossa kutsutaan die-funktiota jolla tulostetaan VIRHE ja PDO:n heittämä poikkeus ja lopetetaan skriptin suoritus.
Edit: Torgo näköjään kerkesikin jo vastaamaan.
Tuossa kyseisessä esimerkissä catchilla ei ole yhtään mitään merkitystä. Try-catch-rakenteen tarkoitus on suojata ohjelmaa mahdollisilta poikkeuksilta. Jos poikkeusta ei catchata, ohjelman suoritus pysähtyy välittömästi. Try-catch:n kanssa virheen tapahtuessa suoritetaan catch-lohkossa oleva koodi, jonka avulla voidaan reagoida tapahtuneeseen virheeseen hienostuneemmalla tavalla, kuin väkivaltaisesti pätkäisemällä ohjelman suoritus siihen paikkaan.
Oletusarvoisesti PHP pysäyttää suorituksen ja näyttää poikkeuksen virheviestin ($e->getMessage()). Siis, jos lohkoon ei ole mitään muuta lisättävää eikä virheen jälkeen ole mahdollista tai tarpeellista suorittaa muuta koodia, niin try-catch on täysin turha.
The Alchemist kirjoitti:
Tuossa kyseisessä esimerkissä catchilla ei ole yhtään mitään merkitystä.
Miten niin ei ole mitään merkitystä? Mieluummin haluan hieman itse virheestä kertovan ilmoituksen, mitä parse errorin.
Vertaa ilman catchia
Parse error: parse error, expecting `T_CATCH' in file on line 17
Catchilla
VIRHE: SQLSTATE[28000] [1045] Access denied for user 'antti'@'localhost' (using password: YES)
Parse error ei tarkoita poikkeusta vaan kirjoitusvirhettä, you fail.
Mutta joo, näköjään sitä outputtia tuli enemmänkin kuin pelkkä poikkeuksen sisältämä virheviesti. PHP printtaa oletuksena myös ns. stack tracen poikkeuksen perään. Se on tässä tapauksessa myös tietoturvan kannalta aika huono asia, koska tulosteessa näkyy yhteyden aukaisuun käytetty funktiokutsu kokonaisuudessaan käyttäjätunnuksen ja salasanan kanssa.
Osoita kyseisestä kohdasta se kirjoitus virhe, jonka catchen pois jättäminen tuottaa.
try { $yhteys = new PDO("mysql:host=localhost;dbname=testit", "antti", "abc"); }
Huoh! PHP-tulkki kertoi sen jo sinulle: virhe on puuttuva catch-lohko.
Try-catch-rakenteessa on pakko olla vähintään yksi catch-lohko. Try-catch ei ole sama asia kuin if-else, jossa ei välttämättä tarvitse olla kuin pelkkä if-osio.
The Alchemist kirjoitti:
Tuossa kyseisessä esimerkissä catchilla ei ole yhtään mitään merkitystä.
Eli kyseisessä esimerkissä catchilla on varsin suuri merkitys. Mutta nyt menee kyllä jo aikalailla ohi aiheen, joten lopetetaan tähän.
Totesin tuon jo ihan omin avuin pienen pohdiskelun jälkeen. Yritys hyvä ykkönen, päteminen nolla. Try-catchin toiminnan selvittäminen on mielestäni silti hyvin relevanttia.
Kuten sanoin, niin catcheja on oltava vähintään yksi. Niitä voi siis olla useitakin. Tuossa aloituspostauksessa annetussa esimerkissä catch nappaisi vain PDO:n omat poikkeukset (PDOException). Jos PDO-olion alustuksessa tapahtuisi jokin muunlainen poikkeus, niin kyseinen catch ei siitä välittäisi lainkaan.
Mikäli haluaa napata kaikki mahdolliset poikkeukset, niin tulee käyttää seuraavaa catchia: catch (Exception $e) { }. Poikkeuksien seulomisessa on se etu, että erityyppisiin poikkeuksiin voi reagoida eri tavalla, tai ne voi jopa käsitellä täysin eri paikoissa.
Laajennettu versio annetusta esimerkistä:
function runMyCodeWithException() { throw new MyException('Viesti'); } function foo() { throw new Exception('Mikä lie poikkeus'); } try { $yhteys = new PDO(...); runMyCodeWithException(); foo(); } catch (PDOException $e) { exit('Tapahtui PDO-virhe.'); } catch (MyException $e) { exit('Tapahtui oma virhe.'); } catch (Exception $e) { exit('Tapahtui jokin muu virhe.'); }
Aihe on jo aika vanha, joten et voi enää vastata siihen.