17
Tags:
php
Skrevet af
Bruger #8222
@ 23.10.2006
Viden som du bør have.
Du bør kende til alle standard funktionerne og control flow (hvilket vil sige print, echo, if-statements og så videre) og vide hvordan du slår op i manualen, og forstår den selvfølgelig
Tip til manulenDu kan altid bare skrive i din adressebar:
http://php.net/DIN_FUNKTION så prøver den at finde funktionen "DIN_FUNKTION", og hvis den ikke findes, prøver den at genkende eventuelle tastefejl
Den røde tråd i artiklen
Her i part 1 vil jeg komme ind på det grundlæggende omkring objekter i PHP5.
Jeg vil forklare hvordan man laver et objekt og komme ind på de forskellige scopes.
Jeg tager udgangspunkt først i at lave en bil, som har følgende funktioner start, stop og kør.
Senere i artiklen vil jeg udvide første klasse (bil) til en rutebil, med benzin beregning og passagerer antal osv.
Jeg vil prøve at komme med nogle eksempler og så forklare ud fra dem, det har jeg altid lært mest af.
Hvad er objekter?
Et objekt kan f.eks. være følgende
• Bil
• Hus
• Dør
• Hund
Dette er bare eksempler på hvad det kunne være, du finder nok en bedre løsning og sammensætning, når du har fået rigtig godt styr på klasser, objekter osv.
Basis definitionerClass = en skabelon til objektet, denne vil indeholde alle de muligheder og oplysning som objektet har.
Nu starter vi på vores bil projekt
Først erklærer vi en klasse, der hedder Bil og opretter derefter et objekt, som vi putter i en variable ($mors_dyt)
<?php
class Bil
{
//
// Herinde imellem de to tuborgklemmer, vil alle funktioner og variabler osv. blive kodet.
//
}
// Bemærk der ikke skal semikolon efter en class definition
$mors_dyt = new Bil();
?>
Lige nu laver vores PHP script jo ingen ting, og hvis du prøver at loade den i din browser, får du en helt blank side.
Start og sluk bil
Nu vil jeg prøve og demonstrere et bil objekt, som du faktisk kan få noget respons fra.
Vi laver en bil, som kan starte og slukke motoren, og hele tiden, printer til skærmen, hvad den gør
<?php
// Først laver vi klasse-skabelonen "Bil"
class Bil
{
// Vi laver en lokal variable, med scope public (det kommer vi ind på senere)
public $status;
// Derudover laver vi også en metode (også kaldet function) til at starte bilen
public function Start()
{
$this->status = "Motoren er tændt<br />";
echo $this->status;
}
Her laver vi en funktion som kan stoppe bilen igen :)
public function Stop()
{
$this->status = "Motoren er slukket<br />";
echo $this->status;
}
}
$ford_mustang = new Bil(); // Laver et objekt af klasse-skabelonen "Bil" og ligger den i variablen $ford_mustang
$ford_mustang->Start(); // Kører Start() funktionen i objektet, som er erklæret i klasse-skabelonen
print ("Bil objektets status er: " . $ford_mustang->status . "<br />"); // Her printer vi direkte variablen fra objektet.
$ford_mustang->Stop(); // Kører Stop() funktionen i objektet, som også er erklæret i klasse-skabelonen
?>
Resultat:Motoren er tændt
Bil objektets status er: Motoren er tændt
Motoren er slukket
Først erklærer vi klasse-skabelonen med dets funktioner og variabler.
Vi bruger ordet "public" foran både funktionerne og variablene, den samling af type erklæringer, hedder med lidt "finere" ord "Scopes". Scopet definere hvordan den pågældende funktion/variable skal opføre sig, hvis noget prøver at kalde på det.
Der er 3 slags scopes i PHP
•
public (standard)
•
private•
protectedPublicBetyder at det kan kaldes fra alle steder, og ændres hvis det er en variable. Dette bruges ofte ikke til variabler, da man gerne vil have styr på typen, så f.eks. et felt med produktionsår ikke lige pludselig indeholder en string, altså tekst. Den variable skal kun indeholde heltal, af en eller anden vigtig grund. Så derfor skal værdien, man prøver at sætte til variablen altid tjekkes først, til dette formål bruger man ofte Setters & Getters, det fremgår tydeligt af kildekoden i eksempelet til rutebilen.
PrivateBetyder at det kun kan tilgås fra aktuel klasse-skabelon, det kan ikke bruges uden for klassen.
Hvis vi f.eks. erklærer variablen "bilmaerke" sådan her:
private $bilmaerke;
Kan man ikke kalde det uden for klasse-skabelonen:
1. uden for objektet
print $bil_objekt->bilmaerke; // Vil resultere i en fejl, da variablen er sat som private.
2. funktion inde i objektet
print $this->bilmaerke; // Dette vil fungere helt korrekt.
(hvis der bliver lavet en klasse-skabelon, som er en instance af denne klasse-skabelon, kan den anden ikke modtage eller skrive til disse variabler/funktioner – Dette er ikke forklaret i denne artikel, men alligevel godt at få med)
ProtectedEr næsten det samme som private, bare at klassere der extender (instance of) klassen også kan tilgå variablen. Dette vil jeg ikke gå nærmere ind på, der er rigeligt på internettet omkring at extende klasser..
--------------------
I hver funktion laver man om på $this->status værdi, og printer den derefter.
$this->bruges til at tilgå noget, som er inde i aktuelle klasse. Dette er f.eks. hvis vi i Start() funktionen vil lave om på objektets variable status. Så bruger vi $this->status for at nå denne variable.
Det bruges også til at tilgå funktioner, f.eks. hvis man i Start() funktionen ville kalde Stop() funktionen, skal man skrive: $this->Stop();
Basis bilen
Vi er nu kommet til basis bilen, som vil have de for nådige egenskaber til vores forsøg.
Der er mærke, model, benzin beregning, kilometer tæller, produktions år og status.
Vi vil nu lave nogle få variabler og funktioner.
Variablerne indeholder informationer omkring vores bil. Vi laver følgende variabler:
•
Mærke•
Model•
Produktion år•
Status•
Km tæller•
Benzin i tankenTil de 3 første er der en setter & en getter..
Bil::getMaerke();Bil::setMaerke($maerke);Bil::getModel();Bil::setModel($model);Bil::getProduktion();Bil::setProduktion($aar);Bil:: indikere at vi går ud fra klasse-skabelonen Bil.
getNAVN() returnere den lokale variables værdi, i denne funktion sættes ofte også enheder på.
setNAVN($VÆRDI) sætter en værdi til den lokale variable.
Det var de 3 basis funktioner, hvor man kan sætte en værdi og trække en værdi ud, sådan uden videre.
Til de andre variabler er der lavet funktioner, som skal beregne noget.
Bil::FyldBenzin($l) Fylder benzin på variablen $this->benzin
Bil::Koer($km) Tjekker om der er benzin nok, og får værdierne puttet korrekt ind i variablerne.
Bil::TestBenzin($km) Er den funktion som bruges i
Bil::Koer() til at beregne om der er benzin nok, den går ud fra variablen kmprliter;
Bil::Km2LiterBenzin($km) Den konvertere kilometer til hvor mange liter benzin der skal bruges.
Så er der start og stop som ændre variablen $this->status, som kan hentes via Bil::getStatus();
Til sidst kan lige nævnes constructoren (
__construct() )
Constructoren er en funktion som bliver udført, når man erklærer objektet. Det kan godt tage parametere, som vi gør i vores eksempel, hvor det er en mulighed at sætte mærke, model og produktionsår ved constructoren.
Tip
Ved at man skriver $var = null, gør at det ikke påkræves, og hvis at der ikke er tastet noget i parametere, går den bare ud fra den standard værdi ( i dette tilfælde null)I PHP5 erklæres constructoren altid sådan her:
public function __construct($parametere)I PHP4 erklæres constructoren ved hjælp, af at lave en funktion med samme navn, som klasse-skabelonen.
class.bil.php
<?php
class Bil
{
protected $kmprliter = 7; // Hvor mange kilometer, bilen kan køre på en liter
protected $maerke; // Mærke
protected $model; // Model
protected $produktion; // Produktionsår
protected $kmtaeller; // kilometer tæller
protected $benzin;
protected $status;
public function __construct($maerke = null, $model = null, $produktion = null)
{
// I constructoren sættes variabelerne ind i de lokale variabler.
$this->setMaerke($maerke);
$this->setModel($model);
$this->setProduktion($produktion);
}
public function Start()
{
$this->status = "startet";
}
public function Stop()
{
$this->status = "slukket";
}
public function FyldBenzin($l)
{
$this->benzin += $l; // Her kunne der eventuelt også tjekkes for max indhold.. :) biler kan jo ikke rumme uendeligt benzin.
}
public function Koer($km)
{
if($this->TestBenzin($km)) // Her tjekker vi om vi, har nok benzin til turen.
{
// Hvis vi har, så gør vi følgende
$this->kmtaeller += $km; // Putter kilometerne på vores kmtæller
$this->benzin -= $this->Km2LiterBenzin($km); // Her trækker vi benzinen fra via vores protected funktion
return true;
}
else
return false; // Hvis der ikke er benzin nok, returnere vi det.
}
protected function TestBenzin($km)
{
if($this->Km2LiterBenzin($km) < $this->benzin)
return true;
else
return false;
}
protected function Km2LiterBenzin($km)
{
return $km / $this->kmprliter;
}
public function getMaerke()
{
return $this->maerke;
}
public function setMaerke($maerke)
{
if(is_string($maerke)) // Tjekker om det er den rigtige type, i dette eksempel skal vi bruge string..
{
$this->maerke = $maerke; // Sætte den lokale variable med det argument som er sat i funktionen.
return true; // Returnere successfull
}
else
return false; // Returnere fejl, fordi typen ikke er rigtig
}
public function getModel()
{
return $this->model;
}
public function setModel($model)
{
if(is_string($model)) // Tjekker om det er den rigtige type, i dette eksempel skal vi bruge string..
{
$this->model = $model; // Sætte den lokale variable med det argument som er sat i funktionen.
return true; // Returnere successfull
}
else
return false; // Returnere fejl, fordi typen ikke er rigtig
}
public function getPorduktion()
{
return $this->produktion;
// her kunne vi f.eks skrive
// return "Årgang " . $this->produktion;
// Dette vil resultatere i at vi returnere f.eks "Årgang 1998", unden at ændre på $this->produktions værdien.
}
public function setProduktion($aar)
{
if(is_numeric($aar)) // Nu tjekker vi om det er en talværdi :) fordi vi vil ikke have at brugeren indtaster nittenhundreoghaltres f.eks :)
{
$this->produktion = $aar; // Sætte den lokale variable med det argument som er sat i funktionen.
return true; // Returnere successfull
}
else
return false; // Returnere fejl, fordi typen ikke er rigtig
}
public function getKmtaeller()
{
return $this->kmtaeller;
// Her kunne ville det måske at være en ide, at returnere en enhed, men uden at ændre resultatetet, det vil jo blive lidt svært, når vi så skal putte 20km på kilometer tælleren, og den variablen måske indeholder: "220 km", men hvis $this->kmtaeller kun indeholder 220, kan vi jo let ligge det sammen..
// Og på denne her metode, får vi "udskriftet" til at fungere rigtigt med den korrekte enhed.
// Eksempel:
// return $this->kmtaeller . "km";
}
public function getBenzin()
{
return $this->benzin;
// Eksempel:
// return $this->benzin . "l");
}
public function getStatus()
{
return $this->status;
}
}
?>
Som vi kan se ud fra vores klasse-skabelon, har vi nu en funktionsdygtig bil.
Ekempel på brug af bil objektet kunne f.eks være:
<?php
require_once("class.bil.php");
$min_bil = new Bil("Ford", "Mustang", "1978");
$min_bil->Start(); // starter bilen
$min_bil->FyldBenzin(40); // Fylder 40 liter benzin på $min_bil
print("Der er nu fyldt 40liter benzin på bilen, og den har ialt nu " . $min_bil->getBenzin() . "liter");
if($min_bil->Koer(20) === true)
print("Turen på 20km forløb ganske fin. der var også nok benzin.\\n");
else
print("Turen er aldrib blevet kørt, da der ikke var nok benzin.\\n");
$min_bil->Stop();
// Næste dag
$min_bil->Start();
print("Der er " . $min_bil->getBenzin() . "liter benzin på, efter køreturen igår");
if($min_bil->Koer(1000))
print("Din køretur på 1000km gik fint, du havde nok benzin på. Du har " . $min_bil . "liter tilbage");
else
print("Du er ikke kommet nogle steder, du har nemlig ikke nok benzin til en køretur på 1000km");
$min_bil->Stop();
?>
Rute-bilen
Nu vil vi prøve at udvide vores bil eksempel til en rutebil (bus der tager passagerer med).
Vi vil tjekke hvor mange penge vi tjener, ved kontant afregning. Vi returnere hvor mange penge, man får tilbage, eller hvor meget man mangler.
class.rutebil.php
<?php
require_once("class.bil.php");
class Rutebil extends Bil
{
// Når vi bruger ordet "extends", udvider vi bare fra klasse-skabelonen Bil. Det vil sige vi har alle Bil'ens funktioner og variabler. Dem som er protected & public kan vi bare overskrive og bruge som intet var hændt. Mens hvis en ting er erklæret som private i Bil klasse-skabelonen, kan ikke vi ikke bruge det.
protected $zonePris = 8; // 8kr
protected $bank; // hvor mange penge vi har med.
protected $passagerAntal = 0;
public function BusStopSted_Stop($antal = 0)
{
$this->status = "Holder ved bus stoppe sted";
$this->passagerAntal -= $antal; // hvor mange der står af.
}
public function Passager($zoner, $penge)
{
$pris = $this->udregnPris($zoner);
$returPenge = $this->ReturPris($pris, $penge);
if($pris <= $penge)
{
$this->passagerAntal++;
$this->bank += $pris;
return "Returpenge: {$returPenge} kr";
}
else
return "Mangler at betale: {$returPenge} kr";
}
public function PassagerArray($passagere)
{
$returnArray = array();
foreach($passagere as $passager)
{
$returnArray[] = $this->Passager($passager["zoner"], $passager["penge"]);
}
return $returnArray;
}
public function getPassagerAntal()
{
return $this->passagerAntal;
}
public function getPenge()
{
return $this->bank;
}
protected function UdregnPris($zoner)
{
return $zoner * $this->zonePris;
}
protected function ReturPris($pris, $penge)
{
if($pris < $penge)
return $penge - $pris; // Hvis man får penge tilbage
else
return $pris - $penge; // Hvis man mangler penge
}
}
?>
Eksempel:
rutebil_eksempel.php
<?php
require_once("class.rutebil.php");
$X931 = new Rutebil("Mercedes", "BusXtra", "1972");
$X931->Start();
$X931->FyldBenzin(9000); // overdrevet meget :)
$X931->Koer(2);
// Aalborg - Vesterbro stoppested
$X931->BusStopSted_Stop(0); // Ingen står af
$passagere[] = array("zoner"=> 5, "penge" => 500);
$passagere[] = array("zoner"=> 3, "penge" => 30);
$passagere[] = array("zoner"=> 5, "penge" => 30);
$passagere[] = array("zoner"=> 6, "penge" => 50);
$passagere[] = array("zoner"=> 6, "penge" => 20);
$passagere[] = array("zoner"=> 6, "penge" => 100);
$info_vesterbro = $X931->PassagerArray($passagere); // Modtager return værdien i variablen $info_vesterbro.
$X931->Start();
$X931->Koer(10); // Kør 10km
print("Info ved passagere i aalborg: <br>");
print_r($info_vesterbro);
// Rørholt
$X931->BusStopSted_Stop(0);
print($X931->Passager(5,36.5));
$X931->Start();
$X931->Koer(20);
print("Antal Passagere i rørholt: " . $X931->getPassagerAntal() . "<br />\\n");
// Frederikshavn - banegården
$X931->BusStopSted_Stop(1);
$X931->Start();
$X931->Koer(12);
$X931->Stop();
print("Antal Passagere ved Endestation: " . $X931->getPassagerAntal() . "<br />\\n");
print("Penge optjent: " . $X931->getPenge() . "<br />");
print("Har kørt " . $X931->getKmtaeller() . "km ialt og brugt " . round(9000-$X931->getBenzin()) . "liter benzin.");
?>
Hvad kan dette i det hele taget bruges til?, hvorfor ikke bare gøre det ligesom vi altid har gjort?.
Ved hjælp af objekt orienteret programmering (OOP), åbner der sig mange nye veje, og en lettere måde at gøre det på.
Mange af de forskellige frameworks, hvis ikke alle, der ligger rundt på nettet, bygger på PHP OOP, fordi det er lettere og holde en ordentlig struktur som er meget vigtig. Mange af disse frameworks, bygger på MVC strukturen, som deler beregningerne og udprint hver for sig, hvilke det bliver igen, et meget mere strukturet projekt. (Omkring frameworks og MVC, søg på internettet for mere information)
Afslutning
Eksempel på et brugbart objekt, hvis man er ved at lave et ordre system. Her kunne man oprette en klasse til at håndtere ordre (f.eks kalde den Ordre
og derefter give den metoder, som f.eks. Tilføj, Slet, Rediger osv.
Et andet sted, hvor det kunne være anvendeligt, er I et "sikkerhedssystem", hvor alt bliver tjekket igennem vores sikkerhedssystem klasse.. Men alt dette vil komme med tiden, det gælder dog om at lære det basale først, derefter er det meget nemmere, at finde information på Internettet. Denne artikel, har taget mange af de punkter op, som jeg simpelthen ikke kunne forstå til at starte med. Derved har jeg prøvet og forklare dem.
I er meget velkommen til at give noget feedback
Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.
Del også gerne artiklen med dine Facebook venner:
Kommentarer (10)
Lige en gang ordbog, så vil artiklen være rigtig god.
Ja det kan der godt være noget om ;=)...
Men arbejder på det (!)
Mån dog, min næste artikel ikke bliver lidt bedre?
Syntes faktisk det er en ganske udemærket artikkel, har ikke prøvet dine eksempler men blot læst det hele, og det ser rigtig godt ud.
Du forklare dine ydtryk og begrunder godt og hele teksten er velformuleret og let læselig, hvilket giver en lyst til at læse hele artiklen.
Du for 4 point af mig, det manglende er begrundet, som sagt her over, at der er nogle små ting som kunne være uddybet lidt mere, og bedre.
En god introduktion til OO i PHP!
Hvis man er interesseret i en dybere forklaring til OO i PHP kan jeg varmt anbefale bogen "PHP 5 Objects, Patterns, and Practice".
Kan desuden også anbefale følgende PHP IDE der understøtter OO i PHP:
- PHP Designer 2007 - Professional (dansk!!!)
- Zend Studio (engelsk)
- Nusphere PhpEd (engelsk)
Jeg bruger selv PHP Designer 2007 - Professional til dagligt, og er virkelig imponeret over dens features - og så er det hvis skrevet af en dansker!!!
Så vidt jeg husker kan programmet hentes via sitet www.mpsoftware.dk
/Martin
Meget flot arbejde.
Det var også lige de ting jeg har haft problemer med at forstå. Men jeg synes dog at dit eksempel med den færdige bil klasse har alt for mange funktioner, i forhold til at det kun er et generelt eksempel. Det gør den en anelse rodet, men godt lavet
jada
hey hvordan kan det være at man ikke kan sætte koden ind på website ? jeg har en på www.webbyen.dk
og jeg har sat koden ind
kan du hjælpe skriv venligst på ospilo@hotmail.com
Altså, det er ik den mest advancerede artikel, jeg har læst om objekter i PHP, og den er heller ikke så dyb, men alligevel giver jeg 4, for nu har jeg endelig fattet det, og det fortjener den.
Glæder mig i synes om artiklen.
Lige som Martin Coles, vil jeg også varmt anbefalde bogen "PHP 5 Objects, Patterns, and Practice", om ikke andet som opslagsbog. Det der står deri, findes ikke bedre på "små" tutorials som f.eks. denne.
Jeg vil også anbefalde at anvende en af de IDE'er, som understøtter OOP, da det gør arbejdet meget mere overskueligt.
OOP er stadig ikke udbredt til php, men det åbner muligheder at have kendskab til det, og eventuelt bruge det til mindre opgaver engang imellem, og stille arbejde sig op til at kunne anvende det meget systematisk.
Til lasse. -> Start med at søg efter noget begynder PHP læring, som også fortæller dig hvordan man sætter en webserver op, og hvad er nødvendigt for at bruge php.
Du skal være
logget ind for at skrive en kommentar.