[PHP] Hoe werp ik hier een exception?

Pagina: 1
Acties:
  • 205 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
Waar gaat het om:
PHP:
1
2
3
4
5
6
7
function fetch( )
{
   // Do stuff
   // Etc ...
   
   return @mysql_fetch_array( $result, $type );
}

Deze functie is onderdeel van een 'databaseschil' en heeft is met de bedoeling geschreven om de feel van de 'echte' mysql_fetch_array() te geven maar toch op een veilig, gecontroleerde en iets uitgebreidere manier (de 'Do stuff').

Maar als het mis gaat krijg ik natuurlijk geen error, maar er wordt ook geen exception opgeworpen zoals dat in de andere functies wel kan gebeuren omdat die niet direct een functie returnen.
Vb:
PHP:
1
2
3
4
5
6
7
8
9
function iets( $blaat )
{
   if ( ! is_numeric( $blaat ) )
      { throw new Exception( 'Iets is mislukt!' ); }

   // Do stuff

   return $blaat;
}

Deze functie is dus geen bestaande functie en terplekke verzonnen :+

Hoe kan ik de throw in mijn eerste functie verwerken zonder het mysql_fetch_array() 'gevoel' te verliezen?
Dus dat ie nog altijd bruikbaar is als:
PHP:
1
while( $row = $db->fetch( ) ) { }


Ik zat eraan te denken het in de functie te doen en een array terug te geven maar dat geeft weer extra 'onvertrouwd' werk.
(Het loopen door een array dus, nog eens na het ophalen etc...)


Ik heb hier niets over kunnen vinden, maar het is ook moeilijk uit te leggen in het google tekstveld :+
}

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Inventariseer eens welke error je allemaal zou kunnen krijgen, en bedenk manieren om die al eerder te detecteren dan bij een aanroep van mysql_fetch_array().

Als je bijvoorbeeld een mysql_num_rows() doet en die is succesvol weet je in ieder geval dat je query succesvol is uitgevoerd en of er resultaten zijn.

Acties:
  • 0 Henk 'm!

Verwijderd

Maar het gaat er toch om dat bij een error juist geen query wordt uitgevoerd, en dus ook geen resultaat wordt teruggegeven door jou fetch() functie?

Als ik er zo eens over nadenk kom ik uit op een aparte error functie (zelf aanmaken) welke je dan aanroept binnen je fetch(), en daarna de functie fetch() zelf voortijdig afbreken met return(0); of zoiets?

Wanneer alles dan goed gaat krijg je gewoon je mysql_fetch waarde terug, en zoniet dan krijg je voortijdig al een 0 als waarde terug van je functie.

[ Voor 23% gewijzigd door Verwijderd op 14-03-2007 00:51 ]


Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
Het gaat er juist om dat als mysql_fetch_array fout gaat dat ik dat gewoon niet weet.
Er missen dan gewoon gegevens op de pagina terwijl ik van niets weet zegmaar.

Alle andere zijn afgevangen, geen probleem.
Maar om dit op deze manier te laten werken zie ik eigenlijk geen manier om dit af te vangen.

Ik zou ook m'n vraag kunnen herformuleren:
Kun je zelf een functie schrijven die net als mysql_fetch_array elke keer 1 row returned tot ze op zijn?

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

PHP:
1
mysql_fetch_array(...) or die("Something went sooo wrong");


Zo kan je proberen :)

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
Snakiej schreef op woensdag 14 maart 2007 @ 10:52:
PHP:
1
mysql_fetch_array(...) or die("Something went sooo wrong");


Zo kan je proberen :)
Hij moet niet dood, maar er moet actie ondernomen worden (bijv. dmv die throw)

Acties:
  • 0 Henk 'm!

Verwijderd

Dan zeg je toch ipv or die() -> or mijnerrorfunctie();

Waarbij je mijnerrorfunctie helemaal invult zoals je zelf wilt ;).

Of denk ik nu te makkelijk :+?

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

SH4D3H schreef op woensdag 14 maart 2007 @ 10:46:
Het gaat er juist om dat als mysql_fetch_array fout gaat dat ik dat gewoon niet weet.
Maar waarom zou mysql_fetch_array fout gaan, als je zeker weet dat je een geldige resultset met records hebt? :) En dat kan je wel degelijk checken van tevoren.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
je kunt toch gewoon FALSE returnen ? Of anders een error message

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function iets( $blaat )
{
    if ( is_numeric( $blaat ) )
    { 
       // Do stuff
    }
    else
    {
        return FALSE;
    }

   return $blaat;
}



En in t geval van de mysql fetch dingen, kun je toch mysql_num_rows gebruiken? Als die 0 returned kun je FALSE returnen in je functie.

[ Voor 24% gewijzigd door Cartman! op 14-03-2007 13:05 ]


Acties:
  • 0 Henk 'm!

  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 00:20
offtopic:
Sorry, HK-mode:
Exception

Modbreak:We zitten hier niet in de HK en dat wilden we graag zo houden. Danku.

[ Voor 24% gewijzigd door NMe op 15-03-2007 19:56 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op woensdag 14 maart 2007 @ 12:47:
Dan zeg je toch ipv or die() -> or mijnerrorfunctie();

Waarbij je mijnerrorfunctie helemaal invult zoals je zelf wilt ;).

Of denk ik nu te makkelijk :+?
Je kunt iig geen throw doen.
Dat had ik nl. al getest :)
eamelink schreef op woensdag 14 maart 2007 @ 12:56:
[...]

Maar waarom zou mysql_fetch_array fout gaan, als je zeker weet dat je een geldige resultset met records hebt? :) En dat kan je wel degelijk checken van tevoren.
Geen idee, zou de kans te verwaarlozen zijn?
Cartman! schreef op woensdag 14 maart 2007 @ 13:04:
je kunt toch gewoon FALSE returnen ? Of anders een error message
Ik wil netjes een exception opwerpen zodat dat netjes afgehandeld kan worden mbt logging etc...
En in t geval van de mysql fetch dingen, kun je toch mysql_num_rows gebruiken? Als die 0 returned kun je FALSE returnen in je functie.
Dat zou kunnen, maar zelfs dan, is er geen kans dat mysql_fetch_array fout gaat?


// Edit: Ik zie nu dat ik op m'n pa's PC zit :+
Maaruh, 'it is I' ;)

[ Voor 3% gewijzigd door Verwijderd op 14-03-2007 13:31 ]


Acties:
  • 0 Henk 'm!

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
Ik begrijp volgens mij het probleem niet helemaal. Je kan toch gewoon in de functie fetch() de waarde van @mysql_fetch_array( $result, $type ) opvangen in een lokale variabele, dan kijken of die return waarde correct is, zo nee throw een exception, zoja dan return je die variabele (precies dezelfde constructie als in je iets() voorbeeld dus). Het feit dat je mysql_fetch_array() kan gebruiken in een loop waar je steeds het volgende record terugkrijgt heeft niks te maken met of je nou de waarde van die functie direct doorgeeft met een return of niet. Dat komt puur omdat de interne pointer van je database resource in $result opgehoogd wordt zodat hij naar het volgende record wijst.

[ Voor 4% gewijzigd door ReverendBizarre op 14-03-2007 13:55 ]


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 00:17
//edit: Hier stond onzin..

[ Voor 94% gewijzigd door FragFrog op 14-03-2007 14:57 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
Het feit dat je mysql_fetch_array() kan gebruiken in een loop waar je steeds het volgende record terugkrijgt heeft niks te maken met of je nou de waarde van die functie direct doorgeeft met een return of niet. Dat komt puur omdat de interne pointer van je database resource in $result opgehoogd wordt zodat hij naar het volgende record wijst.
Maar dat werkt dan dus niet als ik alles eerst in een var stop en dan teruggeef?
Want dat is dus wel de bedoeling.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13-09 09:39

Janoz

Moderator Devschuur®

!litemod

Ik snap je probleem eigenlijk niet. Het is al meerdere keren aangegeven dat je je resultaat in een tijdelijke var kunt stoppen. Kijken of het goed gegaan is en deze dan returnen?

PHP:
1
2
3
4
5
6
7
8
9
10
<?php
function fetch( )
{
   // Do stuff
   // Etc ...
   $result = @mysql_fetch_array( $result, $type );
   if $result ===false throw new Expection('fetch error');
   return $result;
}
?>

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    function fetch($result)
    {
        $row = @mysql_fetch_array($result);
        
        // doe hier je check of row valid is
        if ($row == null)
        {
            throw new exception;
        }
        
        return $row;
    }
    
    try
    {
        while ($row = fetch($result))
        {
            echo $row['b_naam'];
        }
    } catch (exception $e) {
        // handle exception
    }


Wat ik bedoelde is dat deze constructie dus gewoon werkt. Als dat is wat je bedoelt dan kan je dat op die manier doen. Als je dus nu bijvoorbeeld een invalid database result resource meegeeft aan fetch() dan gooit hij een exception.

[Edit: te laat...]

[ Voor 5% gewijzigd door ReverendBizarre op 14-03-2007 14:43 ]


Acties:
  • 0 Henk 'm!

  • _eXistenZ_
  • Registratie: Februari 2004
  • Laatst online: 11-09 23:46
Eerlijk gezegd vind ik de @ niet echt een nette oplossing.

Ik zou hiervoor gaan:

PHP:
1
2
3
4
5
6
7
8
9
10
11
function fetch_goede_data($query) {
  if ($result = mysql_query($query) {
    if (mysql_affected_rows > 0) {
        echo $result;
    } else {
      echo false;
    }
  } else {
    echo false;
  }
}


Dan kan je in je script zelf checken offie false is of niet, en eventueel een bericht weergeven. Dat hoort niet hardcoded in je database class imho. :)

[ Voor 186% gewijzigd door _eXistenZ_ op 14-03-2007 15:08 ]

There is no replacement for displacement!


Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
CAIRATH schreef op woensdag 14 maart 2007 @ 14:42:
[knip]
Wat ik bedoelde is dat deze constructie dus gewoon werkt. Als dat is wat je bedoelt dan kan je dat op die manier doen. Als je dus nu bijvoorbeeld een invalid database result resource meegeeft aan fetch() dan gooit hij een exception.

[Edit: te laat...]
I see.
Ik dacht dat dit niet ging, dat je dat slechts 1 enkele rij terug zou krijgen.
Maar dit lijkt te werken :P

Bedankt!
_eXistenZ_ schreef op woensdag 14 maart 2007 @ 15:02:
Eerlijk gezegd vind ik de @ niet echt een nette oplossing.
[knip]
Dan kan je in je script zelf checken offie false is of niet, en eventueel een bericht weergeven. Dat hoort niet hardcoded in je database class imho. :)
Als er iets fout gaat in de class wordt er een exception opgeworpen en wordt dat netjes afgehandeld.
Er wordt gelogd, evt. gemailt etc ...
Als je dat bij elke query in je script moet doen is dat teveel werk voor niets.

[ Voor 38% gewijzigd door SH4D3H op 14-03-2007 15:10 ]


Acties:
  • 0 Henk 'm!

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
_eXistenZ_ schreef op woensdag 14 maart 2007 @ 15:02:Dan kan je in je script zelf checken offie false is of niet, en eventueel een bericht weergeven. Dat hoort niet hardcoded in je database class imho. :)
Laat dat nou juist het hele nut van exception handling zijn (het loskoppelen van error signaling en error handling).

Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
Ik ben er nog mee bezig maar het lijkt erop dat de exception altijd geworpen wordt.
Nadat alle rows zijn opgehaalt 'loopt' ie nog 1 keer en is $row 'false'.
(Dat zei var_dump: bool(false))

Dus zo gaat het ook niet lukken denk ik.
Is er een manier waarop ik bij kan houden hoeveel returns er zijn geweest? (Met num_rows en een tellertje?)

Nu krijg ik dus:
Data
Data
Data
Laastste record
Exception

[ Voor 4% gewijzigd door SH4D3H op 14-03-2007 15:25 ]


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 11-09 13:55
SH4D3H schreef op woensdag 14 maart 2007 @ 00:08:
Hoe kan ik de throw in mijn eerste functie verwerken zonder het mysql_fetch_array() 'gevoel' te verliezen?
Dus dat ie nog altijd bruikbaar is als:
PHP:
1
while( $row = $db->fetch( ) ) { }


Ik zat eraan te denken het in de functie te doen en een array terug te geven maar dat geeft weer extra 'onvertrouwd' werk.
(Het loopen door een array dus, nog eens na het ophalen etc...)


Ik heb hier niets over kunnen vinden, maar het is ook moeilijk uit te leggen in het google tekstveld :+
}
Je while-loop zal niet lopen als je functie een boolean false terug geeft.
Iets als het volgende lijkt me daarom logisch;
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
function fetch( ) 
{ 
   // Do stuff 
   // Etc ... 
   if($returnVal = mysql_fetch_array( $result, $type )) {
    return $returnVal;
   } else {
    throw new Exception( 'Iets is mislukt!' );
    return false;
   } 
} 
?>

Acties:
  • 0 Henk 'm!

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
Het returnen van false is dus ook geen error maar gewoon normaal gedrag van mysql_fetch_array() zodra hij bij het einde van de recordset is. Met andere woorden, mysql_fetch_array() *hoort* false te returnen uiteindelijk. Dat is just hetgeen wat deze constructie mogelijk maakt:

PHP:
1
2
3
4
while ($row = mysql_fetch_array($result))
{

}


Als mysql_fetch_array() nooit false zou returnen zou dat een oneindige loop worden. Je moet dus uberhaupt geen error of exception gooien als je false terugkrijgt want dat hoort. Je kan wel een exception gooien als je bijvoorbeeld null terugkrijgt (zoals in mijn voorbeeld), want dat hoort niet. Dat betekent dat je bijvoorbeeld een invalid result set aan mysql_fetch_array() hebt meegegeven.

Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
if ($row == null) geeft gewoon een exception als de records op zijn.
Ik denk dat het hier gewoon niet mogelijk is een fatsoenlijke exception te werpen :(

Jammer.

PHP:
1
2
$row = @mysql_fetch_array( 'blaat', $type );
var_dump($row);

Geeft: bool(false)

[ Voor 27% gewijzigd door SH4D3H op 14-03-2007 17:01 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13-09 09:39

Janoz

Moderator Devschuur®

!litemod

Hmm, nu ik er even langer over nadenk, die fetch kan eigenlijk nauwlijks een fout opleveren. Meestal levert deze alleen een fout op wanneer de query niet gelukt is, maar dat vang je bij de query al af. Voor de rest is het in php niet echt mogelijk om tijdens het uitlezen van de recordset in je programma door te krijgen dat er iets fout gaat. Gevolg van het pas veel later toevoegen van taal features. Anders had mysql_fetch_array wel een exception kunnen gooien. Alle andere mysql function trouwens ook. Dan hebben we ook niet meer die ranzige 'or functie()' lazy evaluation constructies nodig.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
Blijkbaar geeft mysql_fetch_array() inderdaad geen null terug (ik had het eerder tussen mijn gewone werk door even gauw getest maar kennelijk niet goed opgelet) dus dan houdt het hele verhaal gewoon op. Dan kan je dus nooit weten of de false komt doordat het einde van de recordset is bereikt (of de recordset dus leeg was) of omdat de result resource gewoon helemaal geen database resource is. Dat moet je dan gewoon handmatig met een check afvangen voordat je mysql_fetch_array() aanroept.

De enige andere manier is om je eigen error handler te implementeren en dan set_error_handler() gebruiken. Maar dan moet je daar alsnog gaan uitzoeken wat die error precies is, waar de error precies vandaan komt en aan de hand daarvan actie ondernemen. Ik raad het niet aan, maar als je echt persee iedere mogelijke error uit die functie wil afvangen dan is er geen andere manier.

Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
Ik denk dat ik het maar laat zoals het was dan :)
Er wordt al gekeken of er meer dan 0 results zijn omdat het anders geeneens zin heeft te fetch()'en, maar verder valt er weinig te doen.

Bedankt voor het meedenken iig! :)

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 12-09 20:53
SH4D3H schreef op woensdag 14 maart 2007 @ 10:46:
Het gaat er juist om dat als mysql_fetch_array fout gaat dat ik dat gewoon niet weet.
Er missen dan gewoon gegevens op de pagina terwijl ik van niets weet zegmaar.
Misschien een rare vraag, maar als je onderscheid wilt maken tussen 'false' van mysql_fetch_array(), indien de rijen op zijn, en een echte fout, waarom gebruik je dan niet
mysql_errno?

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • SH4D3H
  • Registratie: Juni 2004
  • Laatst online: 27-02 23:46
Misschien een idee ja :)

Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 20:26
Overigens kun je zelf met behulp van mysql_fetch_field(), mysql_num_fields() en mysql_field_name() prima een eigen mysql_fetch_array() functie maken. "static" is het keyword om op te zoeken.

Ik vraag me wel af welke fout je verwacht te krijgen van mysql_fetch_array(). Ik heb nog nooit meegemaakt dat die niet alle rijen teruggeeft. Mocht er intern toch iets misgaan dan zal PHP je wel met een fatal error om de oren slingeren...

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

Verwijderd

aangezien het toch om een database klasse gaat waarom converteer je de query niet gewoon naar een array, bewaar em in een cache ook handig voor volgende queries en inderderdaad het toverwoord in dit probleem is: static.

als ik de manual zo lees lijkt het erop dat het juist de bedoeling dat mysql_fetch_array false geeft zodat jij weet dat er niet meer rijen zijn. als er echt iets fout geeft php wel een fatal zoniet een segfault error.

kortom lijkt het me zinniger om de rows eerst gewoon in een array te stoppen en vandaaruit met behulp van static de rows fetchen.

links:
http://www.php.net/manual/en/function.mysql-fetch-array.php
http://www.php.net/manual/en/language.variables.scope.php
Pagina: 1