Query afhandeling
Voordat ik een query uitvoer, check ik met mysqli_ping of er nog verbinding is met de database, puur omdat ik dit gewend ben te doen. Maar is dat wel daadwerkelijk nodig? Stel ik wil enkel iemands gebruikersnaam weergeven, hoe kun je dit dan zo efficiënt mogelijk doen? Op dit moment heb ik de volgende code:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php
if (mysqli_ping($mysqli))
{
$query =
"
SELECT username
FROM user
WHERE u_id = " . mysqli_real_escape_string($mysqli, $_SESSION["user_id"]) . "
";
$result = mysqli_query($mysqli, $query);
if (!(mysqli_errno($mysqli)))
{
$user = mysqli_fetch_assoc($result);
?>
<p>Je bent ingelogd als <strong><?= htmlspecialchars($user["username"]); ?></strong>.</p>
<?php
}
else
{
?>
<p>Je bent ingelogd als <strong>Onbekend</strong>.</p>
<?php
}
}
else
{
?>
<p>Je bent ingelogd als <strong>Onbekend</strong>.</p>
<?php
}
?>
if (mysqli_ping($mysqli))
{
$query =
"
SELECT username
FROM user
WHERE u_id = " . mysqli_real_escape_string($mysqli, $_SESSION["user_id"]) . "
";
$result = mysqli_query($mysqli, $query);
if (!(mysqli_errno($mysqli)))
{
$user = mysqli_fetch_assoc($result);
?>
<p>Je bent ingelogd als <strong><?= htmlspecialchars($user["username"]); ?></strong>.</p>
<?php
}
else
{
?>
<p>Je bent ingelogd als <strong>Onbekend</strong>.</p>
<?php
}
}
else
{
?>
<p>Je bent ingelogd als <strong>Onbekend</strong>.</p>
<?php
}
?>
Echter vind ik dit persoonlijk nogal een overkill aan fout afhandeling.
Hoe pakken jullie dit aan?
Gewijzigd op 01/02/2017 13:54:42 door Lord Gaga
Pingen is alleen nodig in specifieke gevallen, bijvoorbeeld als je de status van een server wilt weten voor een dashboard. Gewoon je query naar de server schoppen en controleren of dat goed gegaan is is meer dan voldoende.
Hierbij kloon ik de query-functie met extend in een eigen class. Dan kan je zelf bij de query-functie ingebouwde foutafhandeling bouwen:
http://phptuts.nl/view/26/7/
- Ariën - op 01/02/2017 14:12:39:
En lees ook even de reacties :p. Die tutorial is nogal verouderd.
---
De uitvoering van een of meer scripts duurt meestal niet meer dan enkele milliseconden tijdens welke je, voor het uitvoeren van queries, eerst een verbinding maakt met je database. (tenzij je wellicht van persistente connecties gebruik maakt?)
Als de kans bestaat dat in dit (ultra)korte tijdsbestek je database onderuit gaat dan lijkt mij jouw opstelling niet erg stabiel?
Indien de data in je database vrij complex/uitgebreid is (denk aan iets dat doorkan als administratief systeem) en het niet de bedoeling is dat deze door storingen corrupt raakt dan kun je ook al een hoop afdekken door relaties (foreign keys) en indexen aan te brengen en gebruik te maken van transacties (een batch van queries wordt wel, of in het geheel niet, uitgevoerd).
Ik denk dat je er, als je succesvol een verbinding hebt gemaakt, van uit kunt gaan dat je database voorlopig nog wel even bereikbaar is - even afgezien van mogelijk super inefficiënte code (denk aan queries in loops) die je website op de knieën dwingt.
Kun je anders uitleggen waarom het zo super belangrijk is dat je continu een absolute garantie hebt dat je database up is? En, for that matter, dat je hier op een of andere manier blijkbaar niet van uit kunt gaan?
Gewijzigd op 01/02/2017 15:26:38 door Thomas van den Heuvel
@Thomas Het is niet zo dat ik persé wil dat er een absolute garantie is dat er verbinding is met de database, hoewel ik dit niet erg zou vinden. Ik probeer mijn website gewoon zo goed mogelijk te programmeren, althans, zo ver dat mogelijk is.
Thomas van den Heuvel op 01/02/2017 15:16:31:
En lees ook even de reacties :p. Die tutorial is nogal verouderd.
- Ariën - op 01/02/2017 14:12:39:
En lees ook even de reacties :p. Die tutorial is nogal verouderd.
Maar ik doel op het extenden van de MySQLi-classe en klonen van de query-method.
Of is dat ook achterhaald volgens jouw?
Verder staat het je vrij om een fork op PHPhulp te publiceren. De tutorial is CC, en je helpt er anderen mee. ;-).
- Ariën - op 03/02/2017 15:20:44:
Maar ik doel op het extenden van de MySQLi-classe en klonen van de query-method.
Of is dat ook achterhaald volgens jouw?
Of is dat ook achterhaald volgens jouw?
Wat in die tutorial gebeurt, en waar ik in mijn reactie aldaar aan refereer, is dat de mysqli klasse en de mysqli_result klasse min of meer worden gecombineerd in één methode (die er in eerste instantie ook nog eens van uit gaat dat er altijd PRECIES één resultaat is) en dat dat naar alle waarschijnlijkheid niet zo'n fantastische keuze is.
Begrijp mij niet verkeerd, ik ben helemaal voor het extenden van dit soort klasses in enkele wrappers, maar dan wel graag op de goede manier. Die tutorial slaat op een aantal zeer belangrijke plaatsen de plank gewoon mis.
Om terug te komen op mysqli_ping:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
if (mysqli_ping()) {
// hoera, er is een verbinding, maar...
// ...
// er is geen enkele garantie dat na deze controle de connectie niet
// alsnog overlijdt wat het doel van deze controle compleet verslaat :p
// dus kun je deze controle net zo goed achterwege laten
// ...
}
?>
if (mysqli_ping()) {
// hoera, er is een verbinding, maar...
// ...
// er is geen enkele garantie dat na deze controle de connectie niet
// alsnog overlijdt wat het doel van deze controle compleet verslaat :p
// dus kun je deze controle net zo goed achterwege laten
// ...
}
?>
Er zijn andere, en waarschijnlijk betere, manieren om de integriteit van je data te waarborgen (zie een vorige reactie).
Gewijzigd op 03/02/2017 15:58:26 door Thomas van den Heuvel
Zo helpen we elkaar tenminste! Jij mag dan wel een hoop ervaring hebben, maar vergeet niet dat er ook beginners hier op het forum zitten.
Nou als je even op het bovenstaande linkje klikt vind je daar een compleet epistel. Is dat niet genoeg?
Thomas van den Heuvel op 04/02/2017 01:11:56:
Nou als je even op het bovenstaande linkje klikt vind je daar een compleet epistel. Is dat niet genoeg?
Misschien moet je mijn post eens beter lezen, ik heb niks over een epistel gezegd.
Maar je mag het ook achterwege houden, maar dan leert niemand wat in de praktijk. Vergeet niet dat voorbeelden een belangrijk middel zijn om kennis op te doen. Dus hoe zou jij het dan doen om een query met ingebouwde foutafhandeling uit te voeren??
Gewijzigd op 04/02/2017 10:15:26 door - Ariën -
Daarnaast is een "ingebouwde foutafhandeling" mogelijk niet echt handig. Wanneer je gebruik maakt van een OO-aanpak is het vrij gebruikelijk dat je ook gebruik maakt van try-catch blokken en exceptions. En het hele doel van exceptions is juist een middel om foutafhandeling te kanaliseren / uit te stellen. De foutafhandeling wordt bewust niet ingebouwd maar gedelegeerd naar andere code (in het catch blok).
Ook is de manier waarop je fouten afhandelt afhankelijk van de omgeving. In een ontwikkelomgeving mag de applicatie meestal wel middenin afgebroken worden en de melding op je scherm worden gedumpt. Op een test- of productieomgeving wil je waarschijnlijk een subtielere aanpak waarbij (de output van) fouten worden onderdrukt maar wel ergens worden gelogd zodat je deze terug kunt zien. De implementatie van foutafhandeling is dus ook niet eenduidig.
En om toch een triviaal voorbeeld te geven, hier een reactie die voortborduurt op de eerdere oplossing.
Gewijzigd op 04/02/2017 14:59:48 door Thomas van den Heuvel
In test-opstellingen toon ik gewoon wel de foutmeldingen.
Mogelijk kan je bij de foutmelding een hash tonen die intern verwijst naar de error in de log. Mocht een bezoeker zo aardig zijn om de error door te geven aan de techneuten, dan heeft hij voldoende aan de hash, zonder de betekenis te weten, maar de beheerder kunnen dan zo zien bij welke error het hoort.
Gewijzigd op 05/02/2017 13:20:05 door - Ariën -