welke fetch mode?
Pagina: « vorige 1 2 3 volgende »
Juist op de manier zoals jij het nu doet, gaat het toch mis als ik van database wissel?
Stel ik doe dit:
$row = $db->getRow(PDO::FETCH_ASSOC); // dit stukje code staat dus buiten de databse class
En dan wissel ik van database, maar dan staat in de code nog steeds dit:
$row = $db->getRow(PDO::FETCH_ASSOC);
Dan gebruik ik toch juist de verkeerde define?
cons ASSOC = PDO::FETCH_ASSOC;
Dan zit je of met hetzelfde probleem, of je moet in elke class die je gaat gebruiken elke keer die constantes aanpassen EN je hebt een probleem met het aanroepen ervan. Een class constante kan je namelijk niet zonder classname gebruiken. De manier waarop je de constante dus gebruikt is niet
$row = $db->getRow(ASSOC);
maar:
$row = $db->getRow(Classname::ASSOC);
Gebruik je opeens een andere database class, dan moet je dus ook al deze aanroepen aanpassen. Dat wil je niet.
Dus, je maakt een eigen set aan constantes, met eigen waardes en die hoef je NOOIT meer aan te passen.
Mijn idee was dan om niet dit te doen:
$row = $db->getRow(Classname::ASSOC);
maar dit:
$row = $db->getRow('assoc');
In de getRow functie zou je dan de fetchmode kunnen ophalen door te zetten:
self::$fetch_mode;
Dan wordt de class constant assoc aangeroepen die vervolgens de juiste define teruggeeft.
Ozzie PHP op 23/05/2013 17:11:23:
Wat als men ineens een integer verandert.
Dat kan niet. Een integer blijft een integer in php.
Wat jij blijkbaar niet doorhebt is dat die integer helemaal niets betekent. Die zijn niet gerelateerd aan de PDO constantes. In je database class zal je dus aan de hand van je eigen gedefinieerde constantes moeten bepalen welke database specifieke fetch mode je moet gebruiken. Je zal dus een vertaling moeten maken van je eigen constante naar, in dit geval, PDO fetch constantes.
Toevoeging op 23/05/2013 17:18:03:
Ozzie PHP op 23/05/2013 17:11:23:
$row = $db->getRow('assoc');
Uh, en nu ga je weer terug naar strings? Volgens mij ben ik je kwijt.
Gewijzigd op 23/05/2013 17:17:12 door Erwin H
Zoals ik het zie (correct me if I'm wrong...).
De PDO constante PDO::FETCH_ASSOC heeft als waarde een of andere integer, bijv. (dit verzin ik nu even) 1. Stel ik gebruik niet een PDO database, maar een FOO database dan heb je daar wellicht een constante FOO::FETCH_ASSOC en deze heeft als waarde de integer 3. De waardes voor dezelfde manier van fetchen zijn dus verschillend, maar in je code wil je altijd dezelfde waarde kunnen gebruiken.
Ik wil niet dat als ik een PDO db gebruik ik dit moet doen:
$row = $db->getRow(PDO::FETCH_ASSOC);
en als ik besluit om een FOO database te gaan gebruiken, dat ik dan overal in mijn code de bovenstaande regel moet aanpassen naar:
$row = $db->getRow(FOO::FETCH_ASSOC);
Daarom lijkt het me dus handig om altijd 1 waarde mee te geven 'assoc'.
$row = $db->getRow('assoc');
In de PDO class "vertaal" ik dan de value 'assoc' naar de juiste define. En dat zou je dan via class constants kunnen doen.
In de PDO class krijg je dan:
cons assoc = PDO::FETCH_ASSOC;
en in de FOO class krijg je dan:
cons assoc = FOO::FETCH_ASSOC;
Snap je nu beter wat ik bedoel?
Uiteraard als jij een betere oplossing weet, hoor ik het graag!
1) Je wil geen strings gebruiken om de mode door te geven want dan kan je je vertikken
2) Je wil zonder problemen van database interface kunnen veranderen
3) Je wil bestaande code niet hoeven aan te passen bij een verandering of uitbreiding
Mijn voorstel:
nieuwe class waarin je zelf constantes definieert die de fetch modus aangeven:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
abstract class Ozzie_Fetch(
const ASSOC = 0;
const NUM = 1;
const BOTH = 2;
const INVERTED = 3;
const DOWNUNDER = 4;
);
?>
abstract class Ozzie_Fetch(
const ASSOC = 0;
const NUM = 1;
const BOTH = 2;
const INVERTED = 3;
const DOWNUNDER = 4;
);
?>
In je database object aanroepen doe je nu dus:
In je PDO database class vertaal je dat met een eenvoudig switch:
Code (php)
Even checken of dit aan de uitgangspunten voldoet:
1) Je wil geen strings gebruiken om de mode door te geven want dan kan je je vertikken
-> ja, ik gebruik namelijk een constante die mijn editor kan aanvullen
2) Je wil zonder problemen van database interface kunnen veranderen
-> geen probleem, constantes zijn database class, interface en driver onafhankelijk
3) Je wil bestaande code niet hoeven aan te passen bij een verandering of uitbreiding
-> ook geen probleem, een nieuwe fetch methode zal bij een huidige class gewoon de default gaan gebruiken.
Bovendien, als ik nu een andere driver of interface ga gebruiken die een al bestaande fetch methode niet ondersteunt dan kom ik ook niet in de problemen, omdat ik ook dan gewoon kan terugvallen op een default.
Dit snap ik nog niet helemaal:
Code (php)
Die $mode is dan in feit een integer geworden... en die kan ik dan weer vergelijken met de fetch constants?
Doe ook maar eens
Resultaat: 0/1/2
En dus zou je ook gewoon dit kunnen doen:
Alleen dat wil je niet, want dan krijg je weer 'uh, wat was 0 ook alweer en wat was 1?'.
Ozzie, constants zijn gewoon variabelen. Het enige verschil is dat de waarde van een constant vast (constant) is en van een variabele is hij variabel.
Maar nu ben ik even zo maar hardop aan het denken...
Stel ik doe niet dit:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
abstract class Ozzie_Fetch(
const ASSOC = 0;
const NUM = 1;
const BOTH = 2;
const INVERTED = 3;
const DOWNUNDER = 4;
);
?>
abstract class Ozzie_Fetch(
const ASSOC = 0;
const NUM = 1;
const BOTH = 2;
const INVERTED = 3;
const DOWNUNDER = 4;
);
?>
Maar dit:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
abstract class Ozzie_Fetch(
const ASSOC = 'ASSOC';
const NUM = 'NUM';
const BOTH = 'BOTH';
const INVERTED = 'INVERTED';
const DOWNUNDER = 'DOWNUNDER';
);
?>
abstract class Ozzie_Fetch(
const ASSOC = 'ASSOC';
const NUM = 'NUM';
const BOTH = 'BOTH';
const INVERTED = 'INVERTED';
const DOWNUNDER = 'DOWNUNDER';
);
?>
En in plaats van dit:
Code (php)
Zou ik dan in de PDO class constanten maken:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
<?php
class Ozzie_PDO {
const ASSOC = PDO::FETCH_ASSOC;
const NUM = PDO::FETCH_NUM;
const BOTH = PDO::FETCH_BOTH;
// ...
}
?>
class Ozzie_PDO {
const ASSOC = PDO::FETCH_ASSOC;
const NUM = PDO::FETCH_NUM;
const BOTH = PDO::FETCH_BOTH;
// ...
}
?>
En in de getRow($fetch_method) doe ik dan zoiets:
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
public function getRow($fetch_mode) {
$fetch_mode = self::$fetch_mode;
// ...
}
?>
public function getRow($fetch_mode) {
$fetch_mode = self::$fetch_mode;
// ...
}
?>
Zou zoiets kunnen?
Offtopic:
Wat zijn inverted en downunder voor fetch methodes?
Dat zou kunnen werken, ware het niet dat self::$foo de foo property van de klasse opvraagt, ipv de constante.
Ah oke... en ik kan een constante niet op een andere manier opvragen? Bijv. Ozzie_PDO::$fetch_mode? Of zal dat ook niet werken?
de enige manier die ik kan bedenken zou Ozzie_PDO::{$fetch_mode} zijn.
Ah oké... zal het straks eens gaan testen dan. Het lijkt me wel een mooiere/handigere methode dan de switch implementatie.
Of, lekker lui, via global. Ik weet niet of dat ook classe-overstijgend is, maar is een poging waard.
Wouter J op 23/05/2013 20:46:16:
de enige manier die ik kan bedenken zou Ozzie_PDO::{$fetch_mode} zijn.
Wouter, had jij dit getest? Ik krijg het niet werkend...?
Toevoeging op 23/05/2013 21:26:00:
Ik lijk het nu werkend te hebben via de functie "constant()";
Ozzie PHP op 23/05/2013 20:05:50:
Offtopic:
Wat zijn inverted en downunder voor fetch methodes?
Wat zijn inverted en downunder voor fetch methodes?
ha ha, als iemand die zich 'Ozzie' noemt zou je toch moeten weten waar de term 'downunder' vandaan komt. En inverted zit indezelfde hoek, hoewel je met een beetje goede wil daar nog een echte fetch methode van zou kunnen maken.
Overigens kan je waarschijnlijk best doen wat je wilt, maar zorg dat je jezelf niet blind staart op PDO. De strings die je nu maakt zijn namelijk maakt zijn wel zodanig dat je die PDO constantes er makkelijk van kunt maken, maar krijg je morgen iets heel anders dan lukt het meteen niet meer.
Wat bedoel je met "De strings die je nu maakt zijn namelijk maakt zijn wel zodanig dat je die PDO constantes er makkelijk van kunt maken, maar krijg je morgen iets heel anders dan lukt het meteen niet meer."
Ik kan toch aan iedere string een fetch mode koppelen?
Er is alleen wel 1 probleem mee. Als je morgen een nieuwe fetch methode nodig hebt omdat je een nieuwe database interface gaat gebruiken, dan heb je die niet gedefinieerd in al je oude database classes. Geef je die nieuwe fetch methode dan door in de getRow methode dan krijg je een foutmelding. Dat is dus niet in overeenstemming met mijn uitgangspunt:
Quote:
3) Je wil bestaande code niet hoeven aan te passen bij een verandering of uitbreiding
Gewijzigd op 24/05/2013 10:39:19 door Erwin H
Erwin H op 24/05/2013 10:31:14:
Volgens mij heb ik iets over het hoofd gezien in jouw methode. Naast de algemene constantes, maak je ook nog constantes aan in de PDO class, die dan weer de waarde krijgen van de echte PDO constantes....
Ja, inderdaad.
Erwin H op 24/05/2013 10:31:14:
Er is alleen wel 1 probleem mee. Als je morgen een nieuwe fetch methode nodig hebt omdat je een nieuwe database interface gaat gebruiken, dan heb je die niet gedefinieerd in al je oude database classes. Geef je die nieuwe fetch methode dan door in de getRow methode dan krijg je een foutmelding. Dat is dus niet in overeenstemming met mijn uitgangspunt:
Quote:
3) Je wil bestaande code niet hoeven aan te passen bij een verandering of uitbreiding
Hmmm, daar heb je inderdaad een goed punt. Ik ben wel benieuwd wat daar een goede oplossing voor is.
Sowieso als ik geen fetch method meegeef dan default ik naar de assoc method. Maar wat inderdaad als je in de fetch class een constant aanmaakt die in een ander database type niet bestaat.
Bij PDO is dat trouwens al afgevangen heb ik gemerkt. Als ik een waarde ingeef die niet overeenkomt met een een van de constanten, dan default ie naar de BOTH fetch methode. Maar of iedere database dat zo netjes afhandelt is maar de vraag.
Wat ik zou kunnen doen is een beveiliging inbouwen, waardoor als een constant niet bestaat, hij automatisch terugvalt op de ASSOC methode.
MAAR...
Als ik dan even verder denk. Meteen even een leuk praktijkvoorbeeld (zie ook mijn andere vraag). PDO kent een PDO::FETCH_CLASS methode waarmee een nieuwe class wordt aangemaakt die automatisch gevuld wordt met gegevens uit de database. Lijkt me heel handig, maar ik vermoed dat deze manier van fetchen niet door alle andere databases wordt ondersteund (misschien kun jij dit bevestigen of ontkennen?). Stel nu dat ik zou overstappen op database X, maar in mijn code gebruik ik nog wel de fetch_class methode. Dan zou ik een default kunnen inbouwen dat ie terugvalt op de assoc methode... maar als je heel eerlijk bent, wat heb ik daar eigenlijk aan? Want in de code verwacht je dan dat er een object wordt aangemaakt, terwijl dat nu niet gebeurt, dus alsnog loopt je code compleet de soep in.
Hoe zou je dit volgens jou dan moeten ondervangen? Het enige wat ik me nu kan bedenken is dat je uitsluitend fetch methodes gebruikt die door alle databases worden ondersteund. Alleen dat zou dan weer betekenen dat ik fetch_class niet kan gebruiken, wat me nu juist weer heel handig lijkt. Of ik moet accepteren dat ik (voorlopig) alleen PDO kan gebruiken (waar ik op dit moment overigens geen bezwaren in zie).
Het is een heel verhaal geworden inmiddels. Je hoeft niet overal op te reageren hoor anders kost het jou ook erg veel tijd, maar ik ben wel benieuwd hoe jij dit zou oplossen. Alvast bedankt weer voor je reactie.
Gewijzigd op 24/05/2013 11:30:44 door Ozzie PHP