ugrás a tartalomhoz

Php - hibakezelés

Kérésre törölve 11. · 2011. Május. 25. (Sze), 14.02
Lehet, hogy csak figyelmetlen voltam, de nem találok választ olyan apróságra, hogy például (hangsúlyozom, például! ;) ) amikor egy fopen FALSE értékkel tér vissza, akkor voltaképp mi baja lehet?
Azt látom, hogy a try-catch nagyon sok esetben nem működik, tehát szinte minden hibát figyelni kell. De adott esetben honnan fogom megtudni, mi is okozta a hibát?
Nem akarok saját hibakezelő rutint készíteni. Így esélyem sincs?
 
1

Ellenőrzés

Poetro · 2011. Május. 25. (Sze), 14.28
Mindenképpen jobb előbb ellenőrizni pár dolgot, mielőtt az ember csak úgy csinál egy fopen-t. Például megnézed, hogy a fájl létezik-e és olvasható (is_readable), és ha igen, akkor nyitod csak meg. Amennyiben tudni akarod, hogy miért nem olvasható, ahhoz már több ellenőrzés szükséges. Például alapjában meg kell nézni, hogy az illető egy fájl-e (is_file), megnézheted a fájl jogosultságait (fileperms), megkérdezheted a fájl tulajdonságait (stat), ebből megállapíthatod, hogy mely csoportnak illetve felhasználónak van mihez joga hozzá, valamint a POSIX függvények között találsz párat, amivel megtudhatod, hogy a PHP amit futtatsz milyen felhasználóval illetve csoportban történik.

Természetesen a leglényegesebb, hogy az adott művelethez van-e jogod, és erre az is_readable és is_writeable tökéletesen alkalmasak.

Például:
$filename = 'readme.txt'
if (is_readable($filename) && ($fhandler = fopen($filename, 'r'))) {
  // Sikeresen megnyitottuk a fájlt
}
else {
  // A fájl vagy nem létezik, vagy nem olvasható.
}
2

Köszi, de nem véletlenül

Kérésre törölve 11. · 2011. Május. 25. (Sze), 14.59
Köszi, de nem véletlenül hangsúlyoztam, hogy "például"...
Rengeteg olyan függvénye van a PHP-nek, ami elintézi azzal a hibajelzést, hogy FALSE értékkel tér vissza, de a hiba természetéről semmit sem mond.
Nekem meg régi mániám, hogy szeretem ha adott esetben le tudom kérdezni, mi baja volt x függvénynek.
Arról nem beszélve, hogy a hibák többségének előre történő ellenőrzése elég sok erőforrást igényel, ami általában feleslegesen lassítja a rendszert.

pl., hogy a fentinél maradjunk: fopen. "bedrótozott" elérési útvonalon lévő file-t akarok elérni vele - teszem azt logot vezetek. Felesleges minden írás előtt ellenőrizni, hogy írható-e a file, hiszen egy belőtt rendszeren csak akkor válik elérhetetlenné, ha valami komoly gáz van. Viszont ha elhasal, mégis jó lenne tudni, hogy valami javítható hibáról van-e szó vagy biztosan fatális gond van.
3

Cache

Poetro · 2011. Május. 25. (Sze), 15.51
A fájlrendszer vizsgálatok cachelve vannak, ezért számottevő teljesítménykiesést nem jelentenek, elvégre a PHP belül ugyanezeket a metódusokat hívja meg. Ezen cacheről olvashatsz egy rövidebb leírást a clearstatcache oldalon.

A bedrótozott elérési utakat ugyanúgy ellenőrizni kell, elvégre ott is fennállhat rengeteg lehetőség, ami miatt akár az egész alkalmazásod leállhat, ezért ezeket érdemes ellenőrizni, és naplózni fájlba, adatbázisba, syslog-gal, vagy syslog-ng-vel. Amennyiben a kritikus hibákról még emailt is küldesz magadnak, akkor gyorsan fel tudod deríteni a problémát. Például egy rosszul sikerült restore, merevlemez vagy fájlrendszer hiba, esetleg a fájlok feltöltésekor történt jogosultság problémákra könnyen rá lehet jönni úgy, hogy megfelelően ellenőrzöl és alkalmasint naplózol.

Az utolsó PHP hibát egyébként meglepő módon az error_get_last függvény segítségével lehet lekérdezni. Például:
<?php
@fopen('X.x', 'r');
echo "Error:\n";
var_export(error_get_last());
?>
Error:
array (
  'type' => 2,
  'message' => 'fopen(X.x): failed to open stream: No such file or directory',
  'file' => 'D:\\htdocs\\PHP-1.php',
  'line' => 2,
)
Ugyanakkor a hibák elnyomása, illetve a nem ellenőrzés esetén a hiba bekövetkezése még jobban lassítja a rendszert, mintha beletennél egy ellenőrzést.
5

Asszem, félreértettél - vagy

Kérésre törölve 11. · 2011. Május. 25. (Sze), 18.45
Asszem, félreértettél - vagy én nem értelek.

1. Nem győzöm hangsúlyozni, hogy a fopen csak egyetlen kiragadott példa volt, nem kizárólag rá vagyok kíváncsi, mondhatni: ez csak egy mellékszál. :)

2. Nem ellenőrzés nélküli kódot akarok. Maradva a fopen() példájánál: azt ellenőrzöm, hogy FALSE értékkel tér-e vissza, de nem akarom előre ellenőrizni minden egyes fopen előtt, hogy elérhető-e a file, olvasható-e stb. Akárhonnan nézem, ha berakok még három if-then-else-t egy fopen elé, az elég rendesen növeli a processzor igényt egy forgalmas oldal esetében, mert az interpreternek minden alkalommal át kell rágnia magát rajta. (amíg nem láttam, hogy egy rosszul megírt program a leggyorsabb Itaniumos rendszert is ki tudja fektetni, addig sem hittem abban, hogy a mai processzoroknak nem számít egy-egy plusz utasítás, azóta meg... :) )
Tehát: "bedrótozott" elérési út. Többnyre rendben van, ezért csak annyit nézek,hogy sikeres volt-e a művelet. Nincs rendben? Felőlem annyit lassul a rendszer, amennyit akar, hisz úgyis működésképtelen.

3. Köszi, végülis az error_get_last volt amit kerestem, ha minden igaz. (én valami get_error v. get_message fv.-t kerestem volna és nagyon nem találtam :) )
7

Akárhonnan nézem, ha berakok

Poetro · 2011. Május. 26. (Cs), 14.23
Akárhonnan nézem, ha berakok még három if-then-else-t egy fopen elé, az elég rendesen növeli a processzor igényt egy forgalmas oldal esetében, mert az interpreternek minden alkalommal át kell rágnia magát rajta.

Tudod, én olyan oldalakon dolgozok, ahol napi többszázezer, illetve millió oldalletöltés van, és elárulom neked, nem ezeken az az if/else tételeken fog elbukni a sebesség. Sokkal inkább az I/O rétegen fog múlni, legyen az fájlrendszer, adatbázis vagy hálózati forgalom.
8

Persze, van ami jobban

Kérésre törölve 11. · 2011. Május. 26. (Cs), 16.46
Persze, van ami jobban terheli a gépet, de azért ez sem elhanyagolható, pláne, ha nem csak egy-két esetben fordul elő, hanem "tömegesen".
Nekem meg vannak olyan rigolyáim, hogy felesleges dolgokat nem szeretek beleírni a scriptjeimbe. Én még így szocializálódtam. ;)
4

Példánál maradva

vbence · 2011. Május. 25. (Sze), 15.56
Minden függvény máshogy kezeli a hibákat. A fájl példánál maradva:
$f = fopen ("valami.log", a);
if (!$f)
    throw new Exception("Fájl megnyitási hiba: valami.log");
Minden ellenőrzésnek megvan amaga ár/érték aránya. Ez itt a minimális szint, hogy ne engedd tovább a kódot, ha nyilvánvalóan nem folytatható a művelet.

A kivételnek elérhető (logolható) a callstackje (hívásverem?). A user kaphat egy 5xx-et és esetleg egy azonosítót, amivel a logban benne lesznek az infók. Magyarán nyoma lesz, hogy melyik sorban, milyen körülmények között fordult elő a hiba.

Az már ár/érték kérdése, hogy mennyire automatizálod a hiba lokalizálását. Magyarán beépítesz-e elé létezést és írhatóságot ellenőrző sorokat. Esetleg a fájlműveletek köré írsz egy saját wrapper réteget.
6

Köszi, de épp nem ez volt a

Kérésre törölve 11. · 2011. Május. 25. (Sze), 18.48
Köszi, de épp nem ez volt a kérdés. :)
(lásd fentebb: error_get_last a megoldás - azon meg külön ki vagyok akadva, hogy a try-catch blokkok pont ezen hibákra nem működnek. :( )
9

PHP ilyen

solkprog · 2011. Május. 26. (Cs), 17.38
PHP (még) ilyen. A legtöbb beépített függvény még nem használja a Exception-okat hanem FALSE-kat dob, és/vagy trigger_error okkal vacakol. Ezt szeretnék megszüntetni, lassacskán de írogatják is meg a beépített osztályokat. (pl date)
10

Vettem észre... :) Kár volt

Kérésre törölve 11. · 2011. Május. 26. (Cs), 18.45
Vettem észre... :)
Kár volt előre venni a Java-t és csak utána belemászni a PHP örömeibe.
Bár számomra ez még mindig kevésbé zavaró/irritáló, mint az, hogy mekkora káosz van a függvények elnevezései körül. :(
(gondolok itt olyasmire, hogy hol van benne aláhúzás, hol nincs és hasonlók.)
11

keretrendszer?

solkprog · 2011. Május. 26. (Cs), 20.36
ha ennyire zavar akkor használd az egyik PHP keretrendszert, vagy esetleg írj saját osztályokat amik eltakarják a PHP "káoszát".
vagy maradhatsz a Java vonalon.. ott még talán jobban is lehet keresni...
12

Egyelőre tanulmányozom a

Kérésre törölve 11. · 2011. Május. 26. (Cs), 20.50
Egyelőre tanulmányozom a PHP-t, programozásból nem fogok megélni, úgyhogy számomra a "jobban lehet keresni" nem bír jelentőséggel. ;)
Egyébként gyakorlatilag azt csinálom: saját "keretrendszert" írok. Megnéztem párat, de egyelőre a PHP-t és az objektum orientált gondolkodást próbálom megtanulni, nem akarok még egy tanulnivalót a nyakamba venni. PHP-t 1ébként csak azért, mert az ingyenes tárhelyeken nincs más, fizetősre meg nem fussa...
14

Python

Poetro · 2011. Május. 27. (P), 12.56
Vagy Google App Engine-en futtathatsz Python, Java vagy Go kódot is szintén teljesen ingyenesen.
13

herokun van lehetoseged

Greg · 2011. Május. 27. (P), 12.50
herokun van lehetoseged ingyen rails-t hasznalni. igaz hogy inkabb csak kiserletezesre alkalmas. de ha ennyi nem tetszik a php akkor a ruby-t erdemes kiprobalni.
15

php beepitett fuggvenyek

Tyrael · 2011. Május. 27. (P), 13.09
php beepitett fuggvenyek 99%-ban nem dobnak exceptiont, hanem valamifele notice-t/warning-ot/error-t generalnak.

hiba eseten a beepitett fuggvenyek altalaban false/null ertekkel ternek vissza (konkret fuggveny manualjat nezd meg), ezt ha levizsgalod, akkor utana a error_get_last fuggveny segitsegevel le tudod kerdezni a hibauzenetet hibakoddal.

tovabbi info itt

Tyrael