Objektorienterad programmering i PHP 5, en introduktion.

Objektorientering förkortas ofta OO och är ett vanligt förekommande fenomen inom programmering, speciellt inom Java.

Denna artikel är för dig som är intresserad av vad objektorienterad programmering är, men inte riktigt har satt sig in i det. Jag kommer att vara så grundlig i mina förklaringar som möjligt, så att du sen ska kunna gå på lite mer avancerade artiklar om OOP. Det är dock ett krav att du programmerat i PHP innan, och att du vet hur vanliga funktioner fungerar. OOP i PHP5 är extra intressant, eftersom det är först med PHP5 som PHP tagit steget ut och blivit ett objektorienterat språk att räkna med.

Vad är ett objekt?

När man pratar om objektorientering är det ganska vanligt att man drar paralleller till verkligheten. Man kan säga att ett objekt i programmering är det samma som ett vardagligt objekt, t.ex. en bil. En bil kan ha en färg och ett antal dörrar. Det är bilens egenskaper (properties på engelska). Objektet, bilen, har även ett visst antal uppgifter/metoder (methods på engelska) den kan utföra. T.ex. att köra framåt, backa, svänga och stanna. Samma sak är det med ett objekt i programmeringsvärlden. Här kommer ett exempel på hur en bil skulle kunna se ut om den var programmerad i PHP5:

class.Bil.php
-------------
<?php
class Bil
{
	private $färg;
	private $antalDörrar;
	
	public function __construct()
	{
		echo "Nu skapar vi en bil!";
	}

	public function sväng($håll)
	{

	}

	public function gasa()
	{

	}

	function setFärg($färg)
	{
		if(is_color($färg))
		{
			$this->färg = $färg;
		}
		else
		{
			echo "$färg är ej riktig färg!";
			return false;
		}
	}

	public function getFärg()
	{
		return $this->färg;
	}

	public function setAntalDörrar($antalDörrar)
	{
		$this->antalDörrar = $antalDörrar;
	}

	public function getAntalDörrar()
	{
		return $this->antalDörrar;
	}
}
?>

Om du inte förstod speciellt mycket av det där, så kan du vara lugn, för jag ska förklara det nu. Det här är en klass. Ett stycke inkapslad kod. Med denna kod kan vi skapa ett objekt, dvs skapa en bil. Det gör vi så här:

<?php
include('class.Bil.php');
$objBil = new Bil();
?>

Genom att först inkludera filen med vår klass i, och sen instansera (jag vet att instansera kan verka som ett onödigt jobbigt ord, men du kommer att stöta på det många gånger i objektorienterade sammanhang, så det är lika bara att vänja sig vid det) objektet genom att skriva $objObjekt = new Klassnamn();. Vad man döper själva objektet till är förstås upp till var och en, men det är god programmeringssed att ange obj som prefix, för att det ska vara tydligt att det är ett objekt. Man kan se förhållandet mellan en klass och ett objekt som en ritning på ett hus, och ett färdigbyggt hus, där klassen är ritningen.

När bil-objektet instanseras, så har bilen ingen färg, vilket vi nu ska ändra på. Då får vi använda "->"-operatorn för att komma åt objektets egenskaper och metoder. Det kan se ut så här: $objekt->metod('värde');. För att då sätta en färg på bilen, kan man tänka sig att man hade kunnat skriva:

exempel 1
---------
<?php
include('class.Bil.php');
$objBil = new Bil();
$objBil->färg = 'neongrön';
?>

Men det kan man inte. Detta är för att variabeln $färg är deklarerad som private. Det betyder att det bara är klassen själv som kommer åt den, och ingen utanför. Hade den varit deklarerad som public, som alla metoderna, så hade man kommit åt den utanför klassen. Istället får man skriva:

exempel 2
---------
<?php
include('class.Bil.php');
$objBil = new Bil();
$objBil->setFärg('neongrön');
?>

Varför då, kan man fråga sig. Det är helt enkelt för att man inte ska kunna göra vad som helst med bilens egenskaper. Om du tittar i metoden setFärg(), så ser du att jag hittat på en liten kontroll där. Funktionen is_color() finns förstås inte, men den skapar en kontroll, som gör att man måste sätta det till en korrekt färg. I exempel 1, så finns inte den kontrollen, man hade kunnat sätta färgen till något helt annat än en färg. Och det vill vi ju förstås inte. I PHP4 finns det inget som hindrar en att göra som i exempel 1, eftersom alla metoder och egenskaper är publika. Privata metoder och egenskaper har dock kommit i PHP5. Det finns privata, publika, och skyddade (protected) egenskaper och metoder. Skyddade metoder kan man inte komma åt utanför klassen. Det är enbart andra klasser som ärver från denna klass som kommer åt dem. Mer om arv kommer lite senare.

Samma sak är det med get-metoderna i klassen. De är till för att man ska kunna kontrollera först innan klassen lämnar iväg egenskapen. Det kan vara så att den andra koden inte har rätt att hämta egenskapen, och då ser get-metoden till att kontrollera det. Använd alltid get- och set-metoder, istället för att sätta variabler till publika.

Du kanske undrar vad som menas med $this->. This är helt enkelt en intern pekare, som man använder för att peka på klassens egna egenskaper och metoder. Titta på följande kod:

<?php
class Test
{
	public $test1;

	public function __construct($test2)
	{
		$this->test1 = $test2
	}
}
?>

Tittar man på $test2, så existerar den enbart inom metoden __construct(). $this->test1 existerar däremoti hela klassen. För dig som använt dig mycket av funktioner, så är $this->test1 global för klassen, medan $test2 är intern för en metod.

Konstruktör (constructor)

Som du säkert lade märke till så finns det en funktion i klasserna som heter __construct(). Denna kallas för konstruktören, och den körs när objektet instanseras. Om du hade testat koden:

<?php
include('class.Bil.php');
$objBil = new Bil();
?>

så hade du märkt att Nu skapar vi en bil! hade skrivits ut (titta i klassen överst för att förstå varför). Konstruktören används oftast för att sätta standardvärden på egenskaper, t.ex:

<?php
class Test
{
	private $var;

	public function __construct($var = false)
	{
		if($var)
		{
			$this->var = $var; 
			// Användaren har angett $var, 
			// t.ex: $obj = new Test('var');
		}
		else
		{
			$this->var = 'Standardvärde';
		}
	}
}
?>

Arv

Arv är en av de viktigaste sakerna inom OOP, och det fungerar ungefär så här:

<?php
include('class.Bil.php');

class Volvo extends Bil { }
?>

När man skriver extends Bil, så gör det att klassen Volvo ärver alla egenskaper och metoder från klassen Bil. Detta är väldigt smidigt, eftersom det gör att samma kod inte måste skrivas många gånger. Alla bilar är ju i grund och botten samma sak. De har hjul, kaross, motor, växellåda, etc. Men det finns olika variationer, t.ex. Volvo och Saab. Istället för att då lägga alla dessa grundmetoder i både Volvo- och Saab-klasserna, så skapar vi grundklassen Bil där vi lägger alla gemesamma metoder och egenskaper, och låter Volvo och Saab ärva dessa. På så sätt har vi alla grundmetoder på samma ställe, ifall vi skulle behöva ändra i dem. En sak att tänka på är dock att en klass bara kan ha en förälder. Den kan ha en mormor, och en mamma. Men den kan inte både ha en mamma och en pappa. Lite förklarande kod. Detta fungerar:

exempel 1
---------
<?php
class MorMor { }
class Mamma extends MorMor { }
class Dotter extends Mamma { }
?>

Detta fungerar dock inte:

exempel 2
---------
<?php
class MorMor { }
class FarFar { }
class Mamma extends MorMor { }
class Pappa extends FarFar { }
class Dotter extends Mamma, Pappa { } 
//Dottern kan inte ärva från båda
?>

Vissa menar att för att ett språk ska vara ett äkta OO-språk, så måste det tillåta multi-arv som i exempel 2, medan andra menar att multi-arv för mer nackdelar med sig än fördelar. En nackdel är den berömda diamond of death. Ett exempel:

exempel 3
---------
<?php
class Mamma { }
class Son extends Mamma { }
class Dotter extends Mamma { }
class Kompis extends Son, Dotter { }
?>
        Mamma
        /   \
       /     \
      /       \
    Dotter    Son
      \       /
       \     /
        \   /
        Kompis

Då vet inte klassen kompis vilken version av Mamma den ska ärva, antingen sonens eller dotterns, och det blir pannkaka av alltihop.

Varför OOP?

Förbaskat bra fråga. Ifall du är ensam i ditt programmerande, och du aldrig kodar tillsammans med någon, så är det inte säkert att OOP är något för dig. Det är dock förstås alltid bra att känna till det. Den största fördelen med OOP är att man kapslar in avancerad funktionalitet, och gör den lättåtkomlig. Låt säga att vi har Peter och Adam. De gör ett projekt tillsammans, där Peter sköter den tunga PHP-programmeringen, medan Adam sköter HTML, CSS, och hela den biten. Adam måste ändå göra en del PHP-programmering, men med hjälp av OOP kan det göras väldigt smärtfritt. Adam kanske vill skriva ut en gästbok, och ber Peter skriva en klass till det. Då kan det räcka med att Adam skriver:

<?php
$objGB = new Guestbook();

$objGB->setBackground('yellow');
$objGB->setMessagesPerPage(20);
$objGB->printGuestbook();
?>

Adam behöver inte bry sig om hur koden bakom detta fungerar, det enda han behöver tänka på är att det fungerar. Det är sen Peters uppgift att få det att fungera. På så sätt blir det väldigt lätt att dela upp uppgifter när man är flera stycken på samma projekt. Självfallet kan man även vara flera stycken som skriver klasser, men som ändå inte vet i detalj hur den andres klasser fungerar, bara just att de fungerar.

Sen finns det förstås olika grader av OOP. Man kan välja att bara ha en klass för att hämta och lägga in data i en databas, och skriva resten av koden "som vanligt". Det är ofta lättare att administrera kod som är skriven i OO, eftersom när du ändrar på ett ställe, så ändras det överallt. Det förutsätter ju dock att man gjort "rätt".

Avslutning, och lite tumregler

Även fast jag skrivit klasser på svenska, så bör man alltid använda engelska. Du bör även kommentera din kod på engelska, och ett ganska vanligt sätt att kommentera klasser är:

<?php
/******************************
 * Some info about who has made 
 * the class and what it's for
 ******************************/

class Foo
{
	// Some info about this var
	public $bar;
	
	/******************************
	 *  Some info about this method
	 ******************************/
	public function __construct($bar)
	{
		$this->var = $bar;
	}
}
?>

En annan liten tumregel är att aldrig använda echo inuti klasser, utan alltid använda return. Detta för att det ska vara upp till den som instanserar objektet ifall något ska skrivas ut eller inte. Du bör heller aldrig blanda in HTML inuti dina klasser, eftersom det går emot hela OO-konceptet med att skilja på kod och design. Det blir även väldigt svårt att administrera HTML-koden för någon som inte är insatt i OOP.

Överväg helt enkelt fördelarna mot nackdelarna med detta. Vet du med dig att du skriver väldigt strukturerat, och kommenterar mycket och väl, och att du vet att du aldrig kommer ta med någon annan i ett projekt, så är det nog bäst att fortsätta som du gör. Är du däremot en av många i ett projekt, så är OOP definitivt något för dig. Den enda nackdelen med OOP är att det blir en viss prestandaförlust, eftersom man inkluderar stora klasser och att datan ofta får gå en viss omväg innan den skickas ut för att klasserna ska bli så strukturerade som möjligt. Ett exempel är en databasklass, som först hämtar data från en databas, och inuti klassen loopar in datan i en array, som skickas ut. När den sen skickats ut, så loopas den igenom när det skrivs ut. Det loopas alltså två gånger, till skillnad från ifall man inte använder klasser då det bara behövs en loop. Om du funderar över hur mycket längre tid det tar att skriva en massa klasser, så brukar det vara så att den tid du förlorar på att skriva klasser, vinner du tillbaka när det är dags att felsöka, eftersom det ofta går snabbare än vanligt. Så väg helt enkelt fördelarna mot nackdelarna, och känn efter om det är något för dig.

Tror du att det är något för dig, så experimentera lite med kodsnuttarna i denna artikeln, och skriv egna. Jag kommer snart att lägga upp en ny artikel med lite mer avancerad OOP, så håll utkik efter den!

Externa resurser:
Practical PHP Programming
http://www.hudzilla.org/phpbook/

Skriven av:
Anders Ekdahl, Ekdahl IT
Webbplats: Webbdesign


Se fler PHP guider



kommenteraKommentarer    Antal 0    Medelpoäng 0/10

Bli medlem för att kunna skriva kommentarer!
Logga in om du redan är medlem.


Copyright © 2005 webbdesign.info    Cookies    Gratis statistik till hemsida    sitemap Webbdesign sitemap icon
Använd gärna våra RSS feeds:

Artikel Feed
[XML]
Forum Feed
[XML]

Svenska webhosts:
Svenska Webhotell

Använd gärna denna länk för att länka till oss:

Ny översättning:
Swedish affiliate programs

Är du medlem och vill synas här?
Hör av dig i vårt forum