[PHP] [OOP] Hoe 'overzichtsqueries' aanroepen?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • .Alex
  • Registratie: Augustus 2005
  • Laatst online: 01-08-2022
Hee, hoi, hallo!

Ik zit even in een denkproces hoe ik classes ga gebruiken in een applicatie en kom er niet helemaal uit; ik heb wat advies nodig.

Stel:

Ik heb de volgende class:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class fiets{

function toevoegen(){
}

function wijzigen(){
}

function verwijderen(){
}

etc.

}


Toevoegen, wijzigen en verwijderen doe ik allemaal via deze klasse. Weliswaar gebeurt het in werkelijkheid op een andere manier, maar dat terzijde.

Nu vraag ik me alleen af hoe ik een overzicht van fietsen ga weergeven.

Normaal gesproken zette ik gewoon de query ("SELECT * FROM fiets") in het bestand waar het overzicht zou moeten worden weergeven, alleen ik vraag me af hoe handig dit is. Ik heb het liefst alle queries bij elkaar zodat ze ook makkelijk aangepast kunnen worden.

Ik bedacht me dat ik een soort 'overzichtsklasse' kon maken maar volgens mij kan dat niet de juiste manier zijn.

Mijn vraag aan jullie: Hoe zouden jullie dit aanpakken?

Bedankt alvast!

Acties:
  • 0 Henk 'm!

  • Webgnome
  • Registratie: Maart 2001
  • Nu online
Je kan gebruik maken van een soort van Factory pattern. Deze Factory houdt dan alle informatie bij van de fietsen zoals het aantal etc en geeft dus ook een overzicht van fietsen terug aan de hand van een query bijvoorbeeld.

Strava | AP | IP | AW


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

*wijst naar sig en fluit een wijsje* O-)

(oftewel, kijk eens naar een O/R mapper of Active Record iets)

[ Voor 49% gewijzigd door SchizoDuckie op 26-03-2008 11:15 ]

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 00:04
Webgnome schreef op woensdag 26 maart 2008 @ 11:11:
Je kan gebruik maken van een soort van Factory pattern. Deze Factory houdt dan alle informatie bij van de fietsen zoals het aantal etc en geeft dus ook een overzicht van fietsen terug aan de hand van een query bijvoorbeeld.
Een factory creeërt objecten, en heeft niet als taak om bij te houden hoeveel fietsen er zijn, of een list te geven van bestaande fietsen.
Wat jij bedoelt, is een repository. Die maakt gewoon abstractie van de data-store, en kan bv gebruik maken van een OR mapper.

Hier kan je dus bv een query gaan uitvoeren die je alle fietsen teruggeeft. Dan moet jij er wel voor zorgen dat je je objecten opvult.

Aangezien je al methods hebt ala toevoegen / verwijderen / etc... als members van je 'fiets' class, zou je hier ook een static method 'GeefLijst' oid kunnen toevoegen, die je een list van alle bestaande fietsen teruggeeft. (En maak dan niet de fout om voor iedere fiets die je hebt, een select te doen).
Ik hou zo wel niet van deze active record aanpak, maar soit.

[ Voor 29% gewijzigd door whoami op 26-03-2008 11:21 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • .Alex
  • Registratie: Augustus 2005
  • Laatst online: 01-08-2022
whoami schreef op woensdag 26 maart 2008 @ 11:18:
[...]

Een factory creeërt objecten, en heeft niet als taak om bij te houden hoeveel fietsen er zijn, of een list te geven van bestaande fietsen.
Wat jij bedoelt, is een repository. Die maakt gewoon abstractie van de data-store, en kan bv gebruik maken van een OR mapper.

Hier kan je dus bv een query gaan uitvoeren die je alle fietsen teruggeeft. Dan moet jij er wel voor zorgen dat je je objecten opvult.

Aangezien je al methods hebt ala toevoegen / verwijderen / etc... als members van je 'fiets' class, zou je hier ook een static method 'GeefLijst' oid kunnen toevoegen, die je een list van alle bestaande fietsen teruggeeft. (En maak dan niet de fout om voor iedere fiets die je hebt, een select te doen).
Ik hou zo wel niet van deze active record aanpak, maar soit.
Nice! Begrijpelijke taal :-)

Ik zou inderdaad een extra functie in de klasse 'fiets' kunnen aanmaken die een array oid teruggeeft mbv een return.

Ik vraag me af hoe ik die O/R mapper zou moeten toepassen... de attributen van de fiets staan vast en ik dacht dat een objectdatabase juist bedoeld was om die attributen schaalbaar te maken?

Acties:
  • 0 Henk 'm!

Verwijderd

Wat ook leuk is om te gebruiken is:

mysql_fetch_object($query,"fiets");

Dit geeft ipv een normale result, een result terug met daarin objecten van het type fiets.

Acties:
  • 0 Henk 'm!

  • .Alex
  • Registratie: Augustus 2005
  • Laatst online: 01-08-2022
Verwijderd schreef op woensdag 26 maart 2008 @ 11:50:
Wat ook leuk is om te gebruiken is:

mysql_fetch_object($query,"fiets");

Dit geeft ipv een normale result, een result terug met daarin objecten van het type fiets.
php.net geeft het volgende:
"Het optionele argument result_type is een constante en kan de volgende waarden aannemen: MYSQL_ASSOC, MYSQL_NUM, en MYSQL_BOTH."

Hoe pas jij dit toe?

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Persoonlijk zou ik twee objecten maken, namelijk Fiets en FietsManager. Fiets is gewoon een een database entity (FietsID, Merk, Model, Hoogte, WielMaat, etc) en de FietsManager welke een collectie (array) van Fiets(en) bijhoud. FietsManager heeft dan Methodes zoals Delete, Update, Insert, Get en Search.

FietsManager zou in een later stadium een data layer kunnen aanroepen (WebService, Database, Xml). Eventueel zou je op een aantal properties van Fiets lazy loading kunnen toepassen.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Nu online
Ik maak zelf meestal een static method getBaseSql in de objecten. Die is dan te gebruiken in een collectie object. Zoiets:
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
class Fiets {
    private $id;
    private $brand;
    private $numwheels;

    public static function getBaseSql() {
        $sql = 'SELECT 
                    b.`id`,
                    b.`brand`, 
                    b.`numwheels`
                FROM `bicycles` AS b';
        return $sql;
    }
}

class FietsCollection extends Collection {

    public function LoadAll() {
        $this->DB->query(Fiets::getBaseSql());
        while($fiets = $this->DB->fetchObject('Fiets')) {
            $this->addItem($fiets);
        }
    }
}

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • .Alex
  • Registratie: Augustus 2005
  • Laatst online: 01-08-2022
T-MOB schreef op woensdag 26 maart 2008 @ 12:02:
Ik maak zelf meestal een static method getBaseSql in de objecten. Die is dan te gebruiken in een collectie object. Zoiets:
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
class Fiets {
    private $id;
    private $brand;
    private $numwheels;

    public static function getBaseSql() {
        $sql = 'SELECT 
                    b.`id`,
                    b.`brand`, 
                    b.`numwheels`
                FROM `bicycles` AS b';
        return $sql;
    }
}

class FietsCollection extends Collection {

    public function LoadAll() {
        $this->DB->query(Fiets::getBaseSql());
        while($fiets = $this->DB->fetchObject('Fiets')) {
            $this->addItem($fiets);
        }
    }
}
Persoonlijk zou ik aan jouw methode de voorkeur geven. Hij zit logisch in elkaar en is voor mij begrijpelijk. Wat vind de rest van deze methode?

Acties:
  • 0 Henk 'm!

  • Webgnome
  • Registratie: Maart 2001
  • Nu online
.Alex schreef op woensdag 26 maart 2008 @ 12:16:
[...]

Persoonlijk zou ik aan jouw methode de voorkeur geven. Hij zit logisch in elkaar en is voor mij begrijpelijk. Wat vind de rest van deze methode?
Zit inderdaad logisch in elkaar echter zou een object het niet moeten boeien (om het zo maar eens te zeggen) waar dat hij vandaan komt. Hoewel het aanwezig zijn van een dergelijke methode geen probleem oplevert voor de werking er van zou ik het toch in een factory OR mapper zien. Die is dan belast met het ophalen van de gegevens uit de db

Strava | AP | IP | AW


Acties:
  • 0 Henk 'm!

  • .Alex
  • Registratie: Augustus 2005
  • Laatst online: 01-08-2022
Webgnome schreef op woensdag 26 maart 2008 @ 12:19:
[...]


Zit inderdaad logisch in elkaar echter zou een object het niet moeten boeien (om het zo maar eens te zeggen) waar dat hij vandaan komt. Hoewel het aanwezig zijn van een dergelijke methode geen probleem oplevert voor de werking er van zou ik het toch in een factory OR mapper zien. Die is dan belast met het ophalen van de gegevens uit de db
Ik kan me slecht voorstellen hoe zo'n OR mapper eruitziet en hoe ik dit concreet zou kunnen toepassen. Ik heb net het een en ander aan uitleg doorgelezen maar het kwartje valt nog niet. Het is nog te abstract denk ik...

edit:
Ben ondertussen naar dat Pork aan het kijken :)

[ Voor 4% gewijzigd door .Alex op 26-03-2008 13:01 ]


Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Ben ondertussen naar dat Pork aan het kijken :)
Pork of Porky? 8)

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • .Alex
  • Registratie: Augustus 2005
  • Laatst online: 01-08-2022
http://www.schizofreend.nl/Pork.dbObject/

Hmm.. "Porky" klinkt leuker. Ik zou het kunnen renamen O-)

[ Voor 14% gewijzigd door .Alex op 26-03-2008 13:18 ]


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
.Alex schreef op woensdag 26 maart 2008 @ 11:56:
php.net geeft het volgende:
"Het optionele argument result_type is een constante en kan de volgende waarden aannemen: MYSQL_ASSOC, MYSQL_NUM, en MYSQL_BOTH."

Hoe pas jij dit toe?
Kijk in de manual eens naar mysql_fetch_object... niet naar mysql_fetch_assoc.;)

Ikzelf zou overigens ook in mijn Fiets-object een "GeefAlles" method maken welke een array van Fiets-objecten terug geeft.

[ Voor 12% gewijzigd door frickY op 26-03-2008 13:31 ]


Acties:
  • 0 Henk 'm!

  • .Alex
  • Registratie: Augustus 2005
  • Laatst online: 01-08-2022
frickY schreef op woensdag 26 maart 2008 @ 13:29:
[...]

Kijk in de manual eens naar mysql_fetch_object... niet naar mysql_fetch_assoc.;)

Ikzelf zou overigens ook in mijn Fiets-object een "GeefAlles" method maken welke een array van Fiets-objecten terug geeft.
Ik heb het zelfs gecopy-pasted van die pagina. Maar je hebt gelijk, ik zie nu dat ik meer met de reacties bij de betreffende functie kan :-)

Zou je die method in Fiets aanmaken ipv FietsCollection? Of zou je uberhaupt niet met de FietsCollection werken? (Zie post van T-MOB)

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Als Fiets altijd uit jouw database komt kun je het ophalen implementeren in Fiets. Maar waarom zou je de fiets modellen niet direct ophalen via een WebService bij Gazelle zelf? Waarmee je altijd het actuele aanbod kan tonen.

Een fiets is een fiets (entity) en het maakt niet uit of deze uit een busje, de bosjes, Gazelle of Marktplaats komt. Daarom wordt over het algemeen business (de fiets) en de data (fietsCollection/fietsManager) uit elkaar gehouden. Het zogenaamde N-tier model.

Met pork en de methode van t-mob worden eigenlijk de layers door elkaar gehaald. Op langere termijn kan dat development lastiger maken. Welke methode je aanhoud is en blijft natuurlijk jouw keuze.

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

Verwijderd

T-MOB schreef op woensdag 26 maart 2008 @ 12:02:
Ik maak zelf meestal een static method getBaseSql in de objecten. Die is dan te gebruiken in een collectie object. Zoiets:
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
class Fiets {
    private $id;
    private $brand;
    private $numwheels;

    public static function getBaseSql() {
        $sql = 'SELECT 
                    b.`id`,
                    b.`brand`, 
                    b.`numwheels`
                FROM `bicycles` AS b';
        return $sql;
    }
}

class FietsCollection extends Collection {

    public function LoadAll() {
        $this->DB->query(Fiets::getBaseSql());
        while($fiets = $this->DB->fetchObject('Fiets')) {
            $this->addItem($fiets);
        }
    }
}
Goed werkbare oplossing, maar toch een paar kanttekeningen:

- getBaseSql() is nu gebaseerd op Fiets, en wordt direct aangeroepen door FietsCollection, terwijl FietsCollection niet eens weet of al z'n objecten wel van 't type Fiets zijn (beperking van PHP, weet ik). Ik zou FietsCollection zelf een static method getSql geven, evt. afgeleid van die van Fiets, maar bij bv. een DamesFietsCollection afgeleide kun je dan simpel 'where StangAanwezig = false' toevoegen of zo. ;)

- In zowel Fiets als FietsCollection zit nu nogal wat intelligentie die met de database te maken heeft. Daar zou ik een factory tussen zetten die ervoor zorgt dat 't zowel voor Fiets als FietsCollection niet uitmaakt of de data uit een SQL database, een webservice of een csv-file komen.

Maar, voor een specifieke situatie is 't uitstekend werkbaar, en een stuk beter dan een hoop code die je tegenkomt waarbij queries zelfs in de UI layer terugkomen... ;)

Acties:
  • 0 Henk 'm!

  • PainkillA
  • Registratie: Augustus 2004
  • Laatst online: 26-08 19:26
een public static method find aangeven die je vervolgens parameters kan meegeven? ID, kleur,type? En die dan een array met fiets objecten teruggeeft?

Acties:
  • 0 Henk 'm!

  • M55
  • Registratie: September 2003
  • Niet online

M55

Ik zou ook voor ORM gaan, een erg makkelijk te gebruiken generator is qcodo http://www.qcodo.com/
Heb je wel PHP5 voor nodig.

Acties:
  • 0 Henk 'm!

Verwijderd

PainkillA schreef op woensdag 26 maart 2008 @ 20:33:
een public static method find aangeven die je vervolgens parameters kan meegeven? ID, kleur,type? En die dan een array met fiets objecten teruggeeft?
Waar moet die find method dan in zoeken? Een static method is op class niveau, en die heeft als 't goed is geen flauw idee van de eventuele instances die er van z'n class bestaan. Tenzij je die instance als parameter meegeeft, maar dan kun je er beter een gewone method van maken.

Wanneer je die find method in een eigen class onderbrengt (zoek op factory pattern en evt. singleton), dan kan 't wel weer prima werken.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik zou het wiel ook niet opnieuw uitvinden... zat goede (open source) OR mappers of complete frameworks te vinden, naast eerdergenoemden, bijvoorbeeld:

www.cakephp.org (Werkt gewoon lekker)
http://codeigniter.com/ (van de makers van ExpressionEngine) edit: weet eigenlijk niet zeker of hier wel een OR mapper in zit...
enz.

[ Voor 12% gewijzigd door Verwijderd op 26-03-2008 23:58 ]


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Nu online
Verwijderd schreef op woensdag 26 maart 2008 @ 20:10:
[...]
Goed werkbare oplossing, maar toch een paar kanttekeningen:

- getBaseSql() is nu gebaseerd op Fiets, en wordt direct aangeroepen door FietsCollection, terwijl FietsCollection niet eens weet of al z'n objecten wel van 't type Fiets zijn (beperking van PHP, weet ik).
FietsCollection kan prima weten of afdwingen dat er alleen objecten van het type fiets inzitten. Je hebt in PHP5 een 'instanceof' operator, daarnaast kun je een datatype afdwingen als functieparameter:
PHP:
1
2
3
4
function addItem(Fiets $item) {
    $this->_data[] = $item;
}
addItem(new WrongObject()); //->fatal error
Ik zou FietsCollection zelf een static method getSql geven, evt. afgeleid van die van Fiets, maar bij bv. een DamesFietsCollection afgeleide kun je dan simpel 'where StangAanwezig = false' toevoegen of zo. ;)
In werkelijkheid gebruik ik getBaseSql() ook zo, de collectie breidt de query uit met sorteer- en where-clausules. De basisquery plaats ik in het object zelf omdat ik mysql_fetch_object() gebruik om platte data in objecten om te zettem. De veldnamen moeten daardoor 1 op 1 overeenkomen met de properties. Het is Ik vind het prettiger om dat in een bestand te onderhouden.
In zowel Fiets als FietsCollection zit nu nogal wat intelligentie die met de database te maken heeft.
Dat klopt, ik maak doorgaans websites waarbij in 99.9% van de gevallen vastligt dat de data uit MySQL gaat komen. Een en ander leunt dus vooral op mysql_fetch_object(): ik vraag direct objecten van het juiste type aan de database.
Daar zou ik een factory tussen zetten die ervoor zorgt dat 't zowel voor Fiets als FietsCollection niet uitmaakt of de data uit een SQL database, een webservice of een csv-file komen.
Het is mooier als het niet uitmaakt, maar mooier is niet altijd nuttig. De eerste klant die producten in zijn webshop wil beheren via marktplaatsadvertenties moet ik bijvoorbeeld nog tegenkomen. Zoals je zelf al aangeeft: het hangt nogal van de specifieke toepassing af.

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

Verwijderd

Goed verhaal T-MOB, en heel erg herkenbaar. En het gros van je klanten vraagt ws niet meer dan een 2-tier (client-server) oplossing en is tevreden met jouw specifieke DataProvider oplossing (let wel, ik noem 'm geen database).
Een klant die 't van de marktplaatsadertenties moet hebben zul je niet gauw vinden, maar denk 's aan een DVD-verkoper die een hoop content uit IMDB kan halen, of een boekenverkoper die kan putten uit de info van Amazon?

Mooier is niet altijd nuttig, maar soms is 't wel nuttig wanneer je je op "mooier" hebt voorbereid... :)

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Het gaat niet om nuttig, maar dat iemand een bepaalde manier van werken aanhoud en dat het daarom routine wordt. Kleine projecten worden vanzelf groot (althans dat is wel de tendens welke ik zie bij de bedrijven waar ik werk). Het is dus altijd goed om een scheiding te hebben tussen presentatie, business en data. En waarom zou een fietsenmaker niet bij marktplaats tweedehands vinden in een straal van 15 km ophalen? Niet iedereen (junks, scholieren, etc) kan (wil) een nieuwe fiets betalen. En door de database queries uit je object te halen wordt je code schoner, heeft een class minder regels en zal daardoor overzichtelijker worden en de fiets kan overal vandaan komen..

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Wat is nu het voordeel van getBaseSQL in de Fiets class te zetten ipv. in de FietsCollection?

FietsCollection zou specifieke condities kunnen leggen op je te selecteren data, en dan moet je toch weten hoe de velden heten. Lijkt me beter om dit allemaal binnen 1 class te houden.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Webgnome
  • Registratie: Maart 2001
  • Nu online
Niemand_Anders schreef op donderdag 27 maart 2008 @ 08:39:
En door de database queries uit je object te halen wordt je code schoner, heeft een class minder regels en zal daardoor overzichtelijker worden en de fiets kan overal vandaan komen..
En kan het object ook weer worden gebruikt in toekomstige projecten aangezien de basis er al ligt

Strava | AP | IP | AW

Pagina: 1