Op deze website gebruiken we cookies om content en advertenties te personaliseren, om functies voor social media te bieden en om ons websiteverkeer te analyseren. Ook delen we informatie over uw gebruik van onze site met onze partners voor social media, adverteren en analyse. Deze partners kunnen deze gegevens combineren met andere informatie die u aan ze heeft verstrekt of die ze hebben verzameld op basis van uw gebruik van hun services. Meer informatie.

Akkoord

Vraag & Antwoord

Webprogrammeren & scripting

[OO PHP] method van de ene class in de andere gebruiken

None
18 antwoorden
  • Hoe gebruik ik de methods van de ene class in de methods van een andere class?
    Voorbeeldje, ik heb een class met database functionaliteit met b.v. de method: database->select($query)
    En ik heb een andere class voor output die b.v. alle namen uit een database op het scherm dumpt. B.v. method: output->dumpnames()

    Nu wil ik dat de method output->dumpnames() "intern" de method database->select($query) gebruikt om de namen uit de database op te halen. Maar op een of andere manier krijg ik het niet voor elkaar.

    Ik heb al overwogen om een aantal 'basis' of 'root' classes te maken zodat ik die kan extenden, daar waar ik ze nodig heb. Op zich geen verkeerd idee, maar in dit geval zou output->dumpnames() dan een extension zijn van database->select($query). En dat lijkt me weer een ramp voor de structuur van mijn classes.
    Dus kan dat niet eenvoudiger?

    [edit]
    Ik kwam net dit tegen om na het overriden van een method toch nog de originele method te kunnen gebruiken:
    parent::do_something($something);
    Wellicht is dit ook bruikbaar voor mijn probleem?
    [/edit]
  • Of je geeft de instantie van Database als parameter mee aan Output. Dan kan je er toch ook gewoon bij?

    [b:5fbbf46094]Edit:[/b:5fbbf46094] Ik ben er al weer eventjes uit, maar mocht het simpelweg doorgeven als parameter niet werken, kijk dan ook even naar Passing by reference.

    - Bas
  • Tnx! Maar laat ik maar heel eerlijk zeggen dat ik het niet begrijp :-)
    De instantie van database als parameter meegeven aan output, wat moet ik me daar bij voorstellen? Eerst in de index de query uit laten voeren en het resultaat naar de output sturen?

    Passing by reference ken ik niet, en het artikeltje gaat er volgens mij van uit dat je weet wat references zijn. Dus veel verder kom ik er ook niet mee :-)
  • Ik heb het niet uitgeprobeerd hoor, maar het is toch simpel als in je methode een nieuwe object aanmaken en vervolgens daarop de methode aanroepen?

    function dupnames(){
    $db = new database;
    $data = $db->select($query);
    ..
    }

    Het zou me iig heel vreemd lijken dat dit niet werkt..
  • ik denk dat je nog een beetje in de knoop met OO zit. Een extensie maken is een optie maar vraag is of dat ook logisch is in dit geval. Ik kan jeverder helpen wanneer je even vertelt in welke klasse dumpnames zit en wat die klasse zoal nog meer kan.
  • [quote:c37f57ef4e="blackhawkdesign"]Ik heb het niet uitgeprobeerd hoor, maar het is toch simpel als in je methode een nieuwe object aanmaken en vervolgens daarop de methode aanroepen?

    function dupnames(){
    $db = new database;
    $data = $db->select($query);
    ..
    }

    Het zou me iig heel vreemd lijken dat dit niet werkt..[/quote:c37f57ef4e]

    Dit zou ik zeker niet doen: niet alleen lijk je nu de functie dumpnames te veranderen, ook ga je daar nu ineens in zetten welke query moet worden uitgevoerd. Dat laatste is een zeer duidelijke overtreding van het principe Separation of Concerns. Alleen wanneer je die scheiding goed toepast, is hergebruik mogelijk. Hiervoor wil ik graag verwijzen naar het boek Normalized Systems. Dit laatste is een vrij nieuwe techniek waarin ik mij momenteel aan het verdiepen ben. Hoewel ze zelf met code-expanders werken (soort van code-generator), zijn de principes ook zelfstandig in programmeerwerk toe te passen.
  • Dumpnames was slechts een voorbeeld. Meer concreet heb ik het nodig in b.v. een class die een serie links uit de database op haalt en de boel in een array aflevert. De class bestaat nog niet, omdat ik dus al redenerend vast liep.

    En ja, ik zit inderdaad regelmatig in de knoop met OO haha. Ik zit eigenlijk nog steeds in de beginnersfase en heb alles via dingetjes op internet geleerd. geen mens die me corrigeert als ik afspraken of protocollen schendt. (Zelfs het MVC principe begrijp ik nog lang niet) Grote kans dus dat het structureel niet goed in elkaar zit.

    Meer concreet, ik zal later vandaag gewoon even de code maken, zover als ik kom, en die met commentaar erbij hier posten. (Moet nu eerst even met dochterlief naar de kapper)

    Achtergrond: Ik ben eigenlijk bezig om een soort van mini frameworkje te maken voor mezelf zodat ik later veel standaard dingen heel snel en gemakkelijk kan implementeren bij het bouwen van een website.
    Waarom ik dan niet een van de talloze, veel betere, reeds bestaande frameworks kies? Omdat ik dit een prachtige gelegenheid vind om OOP te leren. (Ik leer nu eenmaal beter door "in de praktijk" bezig te zijn, dan door een opeenvolging van kleine oefeningetjes te doen). Bovendien moet ik op korte termijn een paar websites opleveren waarbij ik niet de tijd heb om eerst ook nog eens een bestaand framework eigen te maken.
    Plannen zijn er wel: Ik begin binnenkort om de geheimen van CodeIgniter te ontrafelen ;-)
  • [quote:00d36efc3d="marientje"]Hiervoor wil ik graag verwijzen naar het boek Normalized Systems. [/quote:00d36efc3d]Wat is de achtergrond die je voor dit boek moet hebben, cq welke kennis wordt verondersteld? Vermoedelijk ook een boek met veel wiskundige analyses en bewijzen? Lijkt me wel heel erg interessant maar ik moet er wel doorheen kunnen komen in mijn vrije tijd.

    - Bas
  • Nou, daar gaat ie dan

    Niet hier geplaatst, maar op de achtergrond draait er ook nog een config.php met daarin (o.a.) de database gegevens. (Je ziet hem geinclude worden in de database class)

    Verder heb ik een deel van de code net getypt en nog niet getest, dus dit is onder voorbehoud van syntax errors :-) maar het geeft aan hoe ik zit te denken en wat ik probeer te doen.

    Hieronder de index.php van waaruit een lijst met links wordt afgedrukt. Deze links zitten in de database. Daaronder (een deel van) classlib.php met daarin de classes die het moeten gaan doen. Op regel 16 van de classlib zit "mijn probleem" bij de opmerking: " // En hier zou het dan handig zijn om de query naar DBhandling->sqlQuery te sturen…"

    [b:c491980fae]index.php[/b:c491980fae][code:1:c491980fae]<?php
    require_once ("classlib.php");
    $list = new lists();

    // Dump links
    $links = $list->links();
    echo "<ul>
    ";
    foreach ($links AS $link)
    {
    echo "<li>";
    echo '<a href="$link["url"]" title="$link["title"]">$link["text"]</a>';
    echo "</li>
    ";
    }
    echo "</ul>
    ";
    ?>
    [/code:1:c491980fae]

    [b:c491980fae]classlib.php[/b:c491980fae] (Met de twee classes 'lists' en DBhandling)[code:1:c491980fae]<?php
    // Class name: lists
    // Class description: Creates lists with data
    // Constructor: none
    class lists
    {

    // Method name: links
    // Method description: Creates an array with all links in the database table 'links'
    // Method type: public
    // Input: nothing
    // Returns: 2-dimentional array: Array 1 nummeric, array 2 associative with keys: 'text', 'url' and 'title'
    function links()
    {
    $query = "SELECT text, url, title FROM links;";
    // En hier zou het dan handig zijn om de query naar DBhandling->sqlQuery te sturen zoiets als b.v.:
    // $result = DBhandling->sqlQuery($query)

    // Build return-array with requiered keys from array with query result
    $count = 0;
    foreach ($result[queryresult] AS $linkdata)
    {
    $linklist[$count]["text"] = $linkdata[0];
    $linklist[$count]["url"] = $linkdata[1];
    $linklist[$count]["title"] = $linkdata[2];
    $count++;
    }
    return $linklist;
    }
    }

    ///////////////////////////////////////////////

    // Class name: DBhandling
    // Class description: Handles database actions
    // Constructor: none
    class DBhandling
    {
    // Method name: OpenDB
    // Method description: Opens connection to database server and selects a database as defined in config.php
    // Method type: private
    // Input: nothing
    // Returns: $DBstatus - string

    private function openDB()
    {
    require("config.php");

    if ($this->DBconnect = MySql_connect ($_CONFIG["Host"], $_CONFIG["Username"], $_CONFIG["Password"]))
    {
    mysql_select_db($_CONFIG["Database"]) or die();
    $DBstatus = true;
    }
    else
    {
    $DBstatus = false;
    }
    return $DBstatus;
    }

    // Method name: CloseDB
    // Method description: Closes database connection which was opened via the 'openDB' method
    // Method type: private
    // Input: nothing
    // Returns: nothing


    private function closeDB()
    {
    mysql_close ($this->DBconnect);
    }

    // Method name: sqlQuery
    // Method description: performs a regular MySql query
    // Method type: public
    // Input: Sql query - string
    // Returns: Associative array with keys:
    // 'status' (db status - string)
    // 'amount' (number of concerned rows - nummeric)
    // 'queryresult' (two dimensional nummeric array with result rows and result fields - string)
    function sqlQuery($sqlquery)
    {
    $result["status"] = $this->openDB();
    $queryresult = mysql_query($sqlquery);
    if ($queryresult)
    {
    $colamount = mysql_num_fields($queryresult);
    $rowcounter = 0;
    while ($row = mysql_fetch_array($queryresult))
    {
    for ($fieldcounter = 0; $fieldcounter < $colamount; $fieldcounter++)
    {
    $resultarray[$rowcounter][$fieldcounter] = $row[$fieldcounter];
    }
    $rowcounter++;
    }
    }
    else
    {
    $colamount = 0;
    $resultarray = "";
    }
    $this->closeDB();

    $result["amount"] = $colamount;
    $result["queryresult"] = $resultarray;
    return $result;
    }

    }
    ?>[/code:1:c491980fae]


  • EDIT: Een beetje felle reactie van mij dit niet meer nodig is.
  • @gooly: Om dat voor elkaar te krijgen zul je inderdaad zoals in mijn voorbeeld, eerst een object moeten aanmaken en daarop die methode moeten aanroepen. Echter zoals marientje al tegen mij aangaf, is het de bedoeling dat je een programma moet scheiden in verschillende lagen, wat voor jou inhoudt dat je de sql code allemaal binnen je database class moet houden. Binnen de database class kan je dus een methode aanmaken zoiets als GetLinks waarin je die sql code op regel 16 ofzo, stop en vervolgens de resultaten teruggeeft.

    Aangezien je aangaf dat niemand je verbetert, hier wat tips:
    1) Gebruik commentaar op de goede manier, je zet nu in je commentaar de methode en class namen, terwijl ik dit ook wel uit je code kan opmaken. Dit is dus overbodig, gebruik het alleen om extra dingen uit te leggen, die ik niet eenvoudig uit je code kan opmaken.

    2) Probeer beschrijvende namen te gebruiken voor alles.(methodes, classname, bestandsnamen). De methode links zegt mij niks wat het doet. getLinks daarintegen zegt mij dat hij de links voor me op gaat halen. Net zoals bijvoorbeeld de class Lists, ik heb geen idee wat die class moet doen als ik de naam zie.

    3) Probeer elke class een eigen bestand te geven en geef dat bestand ook de naam van je class. Maak geen classlib bestand aan want dit ding groeit binnen korte tijd uit tot een enorm bestand en het wordt erg irritant om te zoeken tussen alle code.

    4) Je dbhandling class zou ik anders aanpakken. Ik zou daarin naast het openen en sluiten van connecties ook een standaard methode aanmaken voor het ophalen, updaten en verwijderen van rijen. Ik zou hem ook gewoon stomweg database noemen. Vervolgens zou ik een concrete database class maken, stel projectDatabase (waarbij project de naam van je project is) die overerft van database. Hier zou ik alle methodes zoals getLinks en andere concrete methodes in stoppen.

    Het boek Code complete geeft veel praktische informatie en tips hoe je je code kan verbeteren.

    Heb je al eens een goed boek gelezen over OO? Zo niet, dan zou ik dat zeker doen. Daarnaast PHP is niet de meest geschikte taal om OO in te beoefenen. Talen zoals c# en java (Heb je ook webvarianten van als je dat wilt: asp.net / jsp) zijn volledig OO en forceren je ook dat je alles in OO doet.

    Succes! :)
  • [quote:4dfe6f6378="BasHamar"][quote:4dfe6f6378="marientje"]Hiervoor wil ik graag verwijzen naar het boek Normalized Systems. [/quote:4dfe6f6378]Wat is de achtergrond die je voor dit boek moet hebben, cq welke kennis wordt verondersteld? Vermoedelijk ook een boek met veel wiskundige analyses en bewijzen? Lijkt me wel heel erg interessant maar ik moet er wel doorheen kunnen komen in mijn vrije tijd.

    - Bas[/quote:4dfe6f6378]
    Nee, dit boek bevat (vrijwel) geen wiskunde. Als je een beetje in bestaande software-ontwikkeling zit, kan je in 1 a 2 avonden de essentie uit het boek halen.
    Het gaat in op hoe informatiesystemen zo kunnen worden opgebouws dat ze elke verandering in de toekomst gemakkelijk aankan - momenteel is het zo dat veel informatiesystemen na een bepaalde tijd niet meer te onderhouden/aan te passen zijn (wet van Lehman). Om dit te overkomen stellen ze vier principes voor, principes die we eigenlijk al heel lang kennen maar waarvan nooit helemaal duidelijk was hoe toe te passen. Ze geven ook voorbeelden van bestaande technologien die hiertegen zondigen.
    Vervolgens stellen ze een set van primitiven (elementen) voor die een bepaalde set van wijzigingen aankan. De claim is dat elke wijziging in een ICTsysteem in die set uit te drukken is. Vervolgens gaan ze nog in op de mogelijkheden en implicaties.
    De theorie rondom Normalized Systems (NS) kan in principe in elke technologie worden toegepast, daardoor is het ook op PHP toepasbaar. Ze hebben zelf een uitwerking gemaakt in Java met Java beans en Apache, deze leggen ze ook in het boek kort uit.

    Ik doe zelf momenteel onderzoek (afstudeerscriptie) in dit gebied. Over niet al te veel tijd hoop ik links naar gepubliceerde artikelen (moeten momenteel nog worden goedgekeurd) en mijn scriptie (ben ik bezig te schrijven) te kunnen posten. Reeds gepubliceerde papers door de auteurs van het boek en PhD studenten onder hen, zijn via de bekende sites te vinden.
  • Om nog even te reageren op de code van de TS:
    ik ben het grotendeels eens met de reactie van blackhawkdesign.
    Ik zou zelf echter niet zo gauw een getLinks methode als extensie van je DBhandler opnemen; ik zou zelf gewoon SQL in je andere klassen laten staan of op een andere manier dáár definieren welke aanroep moet worden gedaan op de database
    [code:1:41e9a2c535]db->select(array('text', 'url', 'title'), 'links', …);[/code:1:41e9a2c535]
    Je kan best een aanroep op je db in de links klasse zetten, je moet dan zorgen dat die klassen die db kent. Ofwel moet je hem dan meegeven in je methode: lists->links($dbhandler) ofwel moet je zorgen dat de lists-klasse deze binnenkrijgt bij constructie (daar is de constructor voor).

    Belangrijke vraag is wel wat de links klasse nu is; het representeert niet echt een object een in de werkelijke wereld. Een dbhanlder is duidelijk: deze beheert de connectie met de database. Een klant-klasse representeert een klant, etc. Maar een links-klasse representeert ??? Dit zou je ook terug moeten zien in de variabelen die deze klasse kent maar de lists-klasse kent die niet. Je moet je afvragen of de links-klasse wel een klasse is. Probeer te definieren wat het is en wat het doet/kan. Dit beantwoord ook de vraag van bhd dan.
  • [quote:580df66d07="marientje"]Ik doe zelf momenteel onderzoek (afstudeerscriptie) in dit gebied. Over niet al te veel tijd hoop ik links naar gepubliceerde artikelen (moeten momenteel nog worden goedgekeurd) en mijn scriptie (ben ik bezig te schrijven) te kunnen posten.[/quote:580df66d07]Graag! Zou er graag eens naar kijken en mij er een beetje in verdiepen.

    - Bas
  • [quote:903b552da0="marientje"]Ik doe zelf momenteel onderzoek (afstudeerscriptie) in dit gebied. Over niet al te veel tijd hoop ik links naar gepubliceerde artikelen (moeten momenteel nog worden goedgekeurd) en mijn scriptie (ben ik bezig te schrijven) te kunnen posten.[/quote:903b552da0]

    Hoewel ik geen bijdrage aan deze thread heb geleverd, vond ik het wel interessant om ideeen van andere ontwikkelaard over OO te lezen.
    Ik ben erg benieuwd naar jouw visie hierop is en zou er dan ook graag (iets) van lezen.
  • is de TS inmiddels geholpen?
  • Ik lees een hele boel bruikbare informatie, waarvoor dank :-)
    @blackhawkdesign: Bedankt voor de tips, daar ga ik zeker wat mee doen. De reden waarom ik ook b.v. de namen van classes en methods in de commentaren zet is omdat ik later eventueel deze commentaren als basis voor documentatie wil gebruiken. Ik had verzonnen dat ik dan later de commentaren zou kunnen isoleren en met de namen er steeds tussen, steeds in hetzelfde format moet het op een of andere manier wel mogelijk zijn om daar steeds een of andere scheiding te laten maken.

    Dat van die aparte bestanden is een erg goed idee. Ik begin me nu al zorgen te maken over de afmetingen van het bestand en bovendien kan ik dan later flexibeler zijn in de zin dat ik alleen hoef te installeren wat ik nodig heb. (Ik denk wel dat ik dan een classlib directory aan ga maken, want ik heb wel de behoefte om de classes op een of andere manier bij elkaar te houden)

    Over OO, het gaat me in de eerste plaats om PHP. Het is dus niet zo dat ik OOP wil gebruiken en daar een goeie taal bij zoek, maar dat ik PHP zo efficient mogelijk wil gebruiken. In feite deed ik voorheen ook al zo iets, maar dan had ik een functies library, en nu dus eentje met classes :-) Ik zie eerlijk gezegd de toegevoegde waarde van objecten boven functies nog steeds niet. Qua werking zijn het totaal verschillende dingen van elkaar, maar zoals ik ze gebruik is het eigenlijk lood om oud ijzer. Maar dat ligt uiteraard aan mijn onervarenheid. Daarom is het ook belangrijk om er meer over te leren.

    @marientje: Inderdaad een goeie tip om classes te vergelijken met objecten in de werkelijke wereld. Als ik ze visualiseer als "echte" objecten dan dwingt me dat meteen in een bepaalde manier van denken. Tot nu toe vergeleek ik ze met gewone functies (zoals je ook al uit mijn opmerking aan blackhawkdesign op kunt maken). Zoals je zegt: 'Probeer te definieren wat het is en wat het doet/kan.'
    Misschien is het zelfs beter om de 'lists klasse' als losse functie te definieren en helemaal niet als klasse.
    Niet in mijn voorbeeld, maar wel in de werkelijke classlib heb ik ook een classe zitten die HTML genereert(adhv. config.php). Die b.v. een hele HTML header uitspuugt, en die een compleet HTML contact formulier uitpoept. Ik vraag me nu ook af of ik dat niet beter uit mijn classes kan halen en er gewoon functies van maken.

    Nou ja, weer een stuk meer inzicht en daar ben ik erg blij mee.
    Nu ben ik de hele topic eigenlijk alleen begonnen omdat ik op zoek was naar de juiste syntax om vanuit de ene klasse een method uit een andere klasse te gebruiken. Inmiddels lijkt die van ondergeschikt belang, want de reakties gaan veel verder en uitgebreider dan dat. Maar om ook die vraag beantwoord te hebben: puur qua syntaxis kan/mag/moet ik dus gewoon een object instantieren binnen een classe, eventueel binnen de contructor, zoals Marientje aangaf(?)

    Tot slot hartstikke bedankt allemaal voor deze (voor mij) schat aan informatie
  • [quote:158dfcc285="Gooly"]@marientje: Inderdaad een goeie tip om classes te vergelijken met objecten in de werkelijke wereld. Als ik ze visualiseer als "echte" objecten dan dwingt me dat meteen in een bepaalde manier van denken. Tot nu toe vergeleek ik ze met gewone functies (zoals je ook al uit mijn opmerking aan blackhawkdesign op kunt maken). Zoals je zegt: 'Probeer te definieren wat het is en wat het doet/kan.'
    Misschien is het zelfs beter om de 'lists klasse' als losse functie te definieren en helemaal niet als klasse.
    Niet in mijn voorbeeld, maar wel in de werkelijke classlib heb ik ook een classe zitten die HTML genereert(adhv. config.php). Die b.v. een hele HTML header uitspuugt, en die een compleet HTML contact formulier uitpoept. Ik vraag me nu ook af of ik dat niet beter uit mijn classes kan halen en er gewoon functies van maken.
    [/quote:158dfcc285]
    Het is niet zo dat alles wat niet in de werkelijkheid kan bestaan een functie moet worden. Je kunt hier zelfs denken aan een klasse HTMLgenerator. Belangrijk is dan wel wat is dat ding (variabelen) en wat kan het ding (methoden).

    Houdt ook goed het onderscheid tussen klasse en instantie: van een klasse Customer is het logisch om meerdere instanties te hebben (klanten). Van een klasse HTMLgenerator is het wellicht mogelijk om meerdere instanties te hebben (voor verschillende onderdelen/modules in je website). Van een linkcreator zal iha slechts een instantie zijn. Je moet dan goed kijken of het eigenlijk wel een object is. Je kunt ook eens kijken naar static methoden, die dienen meestal beter voor zoiets: http://php.net/manual/en/language.oop5.static.php

    [quote:158dfcc285="Gooly"]
    Nou ja, weer een stuk meer inzicht en daar ben ik erg blij mee.
    Nu ben ik de hele topic eigenlijk alleen begonnen omdat ik op zoek was naar de juiste syntax om vanuit de ene klasse een method uit een andere klasse te gebruiken. Inmiddels lijkt die van ondergeschikt belang, want de reakties gaan veel verder en uitgebreider dan dat. Maar om ook die vraag beantwoord te hebben: puur qua syntaxis kan/mag/moet ik dus gewoon een object instantieren binnen een classe, eventueel binnen de contructor, zoals Marientje aangaf(?)
    [/quote:158dfcc285]
    Ja dit klopt, maar als je al een database-connectie hebt, dan moet je die dus meegeven aan je klasse(constructor) of methode en niet opnieuw aanmaken in die klasse.

Beantwoord deze vraag

Dit is een gearchiveerde pagina. Antwoorden is niet meer mogelijk.