15 berichten aan het bekijken - 1 tot 15 (van in totaal 15)
  • Q:
    Bijdrager
    The JM

    OOP met PHP: Doe ik het zo goed?

    Ik ben eens begonnen om PHP object georiënteerd te gaan schrijven. Heb een tutorial gevonden en ik heb een simpele klasse geschreven die de html-code uit een database haalt.

    Dit is mijn eerste object georiënteerde code, dus er zal nog veel op aan te merken zijn. Al die opmerkingen hoor ik graag, brand maar los:)

    _init.php:

    <?php</p>
    <p>// ===========<br />
    // ! Classes<br />
    // =========== </p>
    <p>class connection<br />
    {<br />
    	private $server, $username, $password, $database, $result;<br />
    	protected $row;</p>
    <p>	function __construct()<br />
    	{<br />
    		$this->server 	= 'localhost';<br />
    		$this->username	= 'root';<br />
    		$this->password	= 'mamp';<br />
    		$this->database	= 'demo';</p>
    <p>		$this->connection = mysql_connect($this->server, $this->username, $this->password);<br />
    		unset($this->username, $this->password, $this->server);</p>
    <p>		mysql_select_db($this->database, $this->connection);<br />
    		unset($this->database);<br />
    	}</p>
    <p>	protected function query($sql)<br />
    	{<br />
    		$res = mysql_query($sql);<br />
    		$row = mysql_fetch_array($res);</p>
    <p>		foreach ($row as $key => $value)<br />
    		{<br />
    			$this->row->$key = $value;<br />
    		}<br />
    	}</p>
    <p>	protected function close()<br />
    	{<br />
    		mysql_close($this->connection);<br />
    		unset($this);<br />
    	}<br />
    }</p>
    <p>class page extends connection<br />
    {<br />
    	public $html;</p>
    <p>	function __construct($pagina_id)<br />
    	{<br />
    		$this->html = $this->get_html($pagina_id);<br />
    	}</p>
    <p>	private function get_html($pagina_id)<br />
    	{<br />
    		$db = new connection;<br />
    		$db->query('SELECT html FROM content WHERE id = '.$pagina_id);<br />
    		$db->close();</p>
    <p>		return $db->row->html;<br />
    	}<br />
    }</p>
    <p>// =============<br />
    // ! Functions<br />
    // ============= </p>
    <p>function print_pre($var)<br />
    {<br />
    	echo '</p>
    <pre>';
    	print_r($var);
    	echo '</pre>
    <p>';<br />
    }

    index.php:

    <? include('_init.php'); ?><br />
    <!DOCTYPE html><br />
    <html lang="nl"><br />
    <head><br />
    	<meta charset="utf-8"><br />
    	<title>Demo.com</title><br />
    </head><br />
    <body><br />
    <?php<br />
    $page = new page(1);<br />
    echo $page->html;<br />
    ?><br />
    </body><br />
    </html>

    EDIT
    Sjees, de code-functie van het forum gooit alles overhoop…

    Bijdrager
    Pieterr
    The op 21 september 2010

    Sjees, de code-functie van het forum gooit alles overhoop…

    Ja, dat is al honderd keer gemeld door diverse forumleden, maar daar gebeurt gewoon geen ene mallemoer mee….

    Bijdrager
    KingAchille

    Je bent vergeten je php code af te sluiten met “?>”
    Ook snap ik je “</p><p>” tags niet goed… PHP kent geen opmaak, dus een paragraph tag is ook helemaal niet nodig…

    Bijdrager
    The JM

    Afsluiten van PHP met ?> is niet nodig als het hele document alleen maar PHP bevat. En die p-tags zijn van de forumsoftware. Als je mijn bericht quote zie je hoe ik het bedoeld heb;)

    Bijdrager
    Jeordy

    De Class is een verzameling functies waarmee je een bepaald resultaat wilt genereren. In je Class stop je dus informatie en krijg je informatie terug. Ik probeer het altijd uit te leggen als een plank met potjes. De plank is de Class, de potjes zijn functies. Elk potje verwacht een bepaalde inhoud en in het potje gebeurt er dan iets mee. Als het potje klaar is dan haal je het resultaat eruit of je krijgt het eruit (return).

    Class A
    {
    function doe_iets($a, $b)
    {
    return $a + $b; // telt $a bij $b op en retourneert de uitkomst
    }

    } // einde class

    Vanuit een pagina stop je er iets in

    $A = new A();

    $a = 5;
    $b = 6;

    $c = $A->doe_iets($a, $b); // var $c krijgt de geretourneerde waarde uit de functie, dus 11.

    echo ‘<p>’.$c.'</p>’;

    Normaliter stuur je vanuit een Class niets naar de browser, behalve als je debugt.

    Bijdrager
    The JM

    Dat klopt, dat doe ik dan toch ook goed of niet?

    Ik wil trouwens in de klasse van de database ook een functie bouwen die alle variabelen escapet. Maar ik weet niet waar ik moet beginnen, wie kan me een beetje op weg helpen?

    Bijdrager
    qazwsxedc

    Of je het zo goed doet kan ik door de brakke weergave niet zien. Wel kan ik iets zinnigs zeggen over ‘ik wil een klasse bouwen voor de database …’, namelijk dat dat wiel al door heel veel mensen uitgevonden is. Als je OO in PHP wil programmeren (en dat wil je), dan doe je er goed aan om je te verdiepen in een framework. In zo’n framework zijn alle gangbare taken die je wil uitvoeren (database, foutcontrole, forms, mail, web services, etc) al beschikbaar en op een goede manier geïmplementeerd. Zo kun je zelf focussen op het bouwen van je applicatie en niet op je database abstractie.

    Zelf ben ik enorm grote fan van het Zend Framework. Naar mijn idee het meest uitgebreide, best gedocumenteerde en best opgezette framework dat er is voor PHP. Door de goede OO structuur ervan kun je bestaande classes goed uitbreiden. Ook het Model-View-Controller (MVC) design-pattern is op een goede manier geïmplementeerd. Het Zend Framework gebruiken wij in projecten van vele tienduizenden regels code en zowel qua performance als qua schaalbaarheid is het erg goed.

    Om optimaal van de mogelijkheden gebruik te maken is het verstandig je goed te verdiepen in de wereld van OO (zorg dat je op zijn minst ‘public, private, protected, static, extends, implements’ begrijpt). Dat, i.c.m. een goed framework zal veel betere applicaties opleveren dan met een eigen framework/classes.

    Een goede start is de ‘Getting started with Zend Framework’ tutorial van Rob Allen. http://akrabat.com/ . Voor lokaal ontwikkelen is Zend Server CE een prima Apache/MySQL/PHP installatie.

    Succes!

    Bijdrager
    tinus_omt

    Een ding wat in ieder geval niet goed is, is dat je page object een extensie is van het connection object, maar dan toch weer een nieuw connection object maakt om bij de database te komen.

    Het is gemakkelijker als je het Singleton pattern gebruikt voor de connection, dan kun je het object als je het nodig hebt opvragen en krijg je steeds dezelfde.

    Het is, tenzij je een configuratiebestand gaat implementeren, niet erg zinvol om de gegevens die je nodig hebt voor de database in properties te stoppen en ze dan meteen weer weg te gooien.

    Als laatste, als je sql queries als strings in elkaar gaat plakken moet je heel erg oppassen dat de invoer is wat je verwacht (in jouw geval een nummer) anders krijg je een beveiligingslek (sql injection). Je kunt eigenlijk beter de moderne Mysqli interface gebruiken. Daarmee kun je zogenaamde prepared statements gebruiken, waarmee je de variabelen los van de query kunt houden. Als je dat doet krijg je die beveiligingslekken niet.

    Bijdrager
    The JM

    Hartstikke bedankt voor jullie reacties!

    @nielsr: Ik weet dat ik het wiel opnieuw aan het uitvinden ben, maar ik denk dat je van dingen namaken ook veel kunt leren en inzicht kunt krijgen.

    @tinus_omt
    : Dus PHP heeft zelf al een ingebouwde klasse om verbinding te maken met de database?

    Is hier trouwens een goed boek over dat jullie me aan kunnen raden?

    Bijdrager
    tinus_omt

    De mysql en mysqli interfaces werken allebei met een soort classes. Een van de redenen dat meestal wordt gekozen om daar toch maar iets omheen te bouwen is dat als je die classes direct gebruikt, je vast zit aan het type database (in dit geval MySQL). Een andere reden is dat je meestal een andere foutafhandeling wil dan PHP standaard aanbiedt.

    Als je de oude interface gebruikt moet je verder de hele tijd de variabelen controleren en quoten en dat gaat gemakkelijker als je zelf een class bouwt die daar functies voor heeft.

    Ik zou je in ieder geval aanraden om eens de documentatie over security te lezen van de php website:

    http://www.php.net/manual/en/security.php

    Bijdrager
    The JM

    Ok, daar ga ik zeker mee beginnen. Maar is er ook nog een goed boek dat de basis en het concept van OOP met PHP uitlegt?

    Bijdrager
    sturb

    Ik vraag me altijd af hoeveel zin een class is als het ook met een ‘gewone’ functie kan. Voor kleinere projectjes.

    <br />
    function kwery($sql){<br />
    	$res = mysql_query($sql) or die(mysql_error());<br />
    	return $res;<br />
    };</p>
    <p>//of<br />
    class Connection<br />
    {<br />
    	protected function __construct()<br />
    	{<br />
    		//maak db<br />
    	}</p>
    <p>	private function kwery($sql){<br />
    		$res = mysql_query($sql) or die(mysql_error());<br />
    		return $res;<br />
    	}<br />
    }<br />
    $result = new Connection;<br />
    $result = $result->kwery('SELECT * FROM tabel');<br />
     

    (overigens is bovenstaande code niet netjes, en niet escaped enzo. Gaat even over de opbouw.

    Bijdrager
    The JM

    Dat klopt, maar bij grotere projecten heb je op den duur zoveel functies dat je het overzicht bijna kwijt raakt. En ik denk dat in zo’n geval ook minder regels nodig zijn als je met klassen gaat werken.

    Bijdrager
    tinus_omt
    sturb op 23 september 2010

    Ik vraag me altijd af hoeveel zin een class is als het ook met een ‘gewone’ functie kan. Voor kleinere projectjes.

    Een aantal voordelen van objecten/classes zijn:

    1. Structuur: Het is gemakkelijker te doorzien wat het programma allemaal doet als je (op een goede manier) objecten gebruikt. De dingen die bij elkaar horen staan vanzelf bij elkaar. Dat zijn niet alleen de functies maar ook variabelen die daarbij horen.
    2. Namespace: De naam van de classe moet uniek zijn, de functies daarin niet. Als je alleen maar functies gebruikt moet je uitkijken dat je niet een naam gebruikt die al iets anders doet. In een object of class kun je verder ook variabelen stoppen terwijl je bij functies al snel globale variabelen gaat maken die de namespace nog meer vervuilen.
    3. Inheritance: Je kunt subclasses maken die net iets anders doen dan de originele class. Dat is erg lastig als je alleen maar functies gebruikt.
    4. Encapsulation: Objecten maken het gemakkelijk om een interface vast te leggen die bepaalt hoe je het object moet gebruiken in plaats van hoe de functionaliteit werkt. De code die het object gebruikt wordt zo afhankelijk van de interface in plaats van de functionaliteit. Als je dan later bedenkt dat het handiger is om het anders te doen, kun je de functionaliteit veranderen en de interface gelijk laten. Dan hoef je alleen maar het object aan te passen en niet alle code die gebruikt maakt van het object.

    In je voorbeeld is het eigenlijk al een beetje te zien, je functie doet heel gemakkelijk mysql_query maar in het echt heb je daar toch al een connectie voor nodig. Die zul je ook ergens op willen slaan want het is nogal inefficiënt om iedere keer een nieuwe te maken. Verder is een beetje meer foutafhandeling dan die() ook geen overbodige luxe. Als je dat toevoegt wordt het al snel ingewikkelder en zijn objecten al snel gemakkelijker.

    Bijdrager
    The JM

    Ik heb Php Object-Oriented Solutions besteld trouwens. Ik ben benieuwd hoe het me bevalt, heb wel verschillende goede recensies gelezen op internet.

15 berichten aan het bekijken - 1 tot 15 (van in totaal 15)

Je moet ingelogd zijn om een reactie op dit onderwerp te kunnen geven.