PHP-konstruksjon: lage forekomster av klasser. Ny objektorientert tilnærming i PHP5

Mulighetene til PHP er betydelig bredere på grunn av dets spesifikasjoner, men selv i den eksisterende implementeringen gir det programmereren ubegrensede muligheter. PHP-konstruksjon er en spesiell metode for en klasse (objekt) som kalles opp hver gang en forekomst av klassen opprettes.

Begrensningen er at PHP fungerer når siden er generert. I det øyeblikket siden oppdateres eller en annen side på samme nettsted lastes inn, dannes det nødvendige systemet med objekter igjen fra bunnen av.

Opprette en forekomst av en klasse

Trenger ikke ha en konstruktør. Hvis du trenger å forberede de innledende verdiene til variabler, fange øyeblikket for opprettelse av en forekomst av en klasse (objekt) og utføre visse handlinger på andre objekter, kan du ikke bruke PHP-klassens konstruksjonssyntaks og skrive tilsvarende kode utenfor klassemetodene.

I henhold til logikken til den objektorienterte programmeringsstilen, må hver klasse ha en konstruktør; dessuten bør klassetreet begynne med den mest abstrakte (absolutt tomme) stamfaren. ikke god praksis.

Når slektstreet begynner med en meningsfull klasse som har sine egne data og egenskaper knyttet til eksterne data (objekter), er PHPs funksjonskonstruksjon uunnværlig.

I dette eksemplet, når du oppretter (PHP-konstruksjon) en forekomst av datoklassen, denne funksjonen(konstruktør). Den har et spesifikt navn __construct og kalles automatisk bare én gang når en forekomst av klassen opprettes.

Denne klassen gir en statisk variabel $iUniqueNo, som i hver ny forekomst av denne klassen vil ha unik verdi. Forekomster av klasser har ingenting til felles med hverandre bortsett fra beskrivelsen innenfor PHP syntaks og samspillet mellom metodene deres levert av utvikleren.

Arver initialiseringslogikk

Hvert objekt må realisere sin hensikt, ha det det skal og gjøre det det skal. Fra et slikt rimelig synspunkt kan initialisering på hvert nivå i stamtavlen inkludere initialisering på hver stamfar som kalles fra etterkommernivå.

I dette eksemplet lar nøkkelordet overordnet:: deg kalle stamfarkonstruktøren fra underordnet nivå. Semantikken er enkel. Stamfaren må initialiseres først, deretter gjeldende forekomst. Den første følger sin egen logikk, den andre følger sin egen.

Når hvert objekt gjør sin egen ting, generell prosess ser riktig og oversiktlig ut. Men denne regelen bør ikke betraktes som normen for alle systemer av objekter.

Stamtavlen til "mat"-objektsystemet, til en aller første tilnærming, kan ha noe til felles, men produktene melk, vannmelon, pasta og frokostblandinger, selv om de tilhører et slikt system, ser ut og beskrives helt annerledes.

Utvikleren må bygge hvert objektsystem basert på anvendelsesomfanget, og ikke på hvordan det en gang ble foreslått av noen. Hver oppgave er unik; kravet om å bruke en PHP-overordnet konstruksjon er ikke absolutt.

Offentlige og private konstruktører

Som standard er konstruktøren offentlig og kan brukes av alle barn. Det er ikke nødvendig å indikere offentlig funksjonskonstruksjon, PHP behandler som standard alt beskrevet som generelt.

I hvilken grad er det fornuftig å bruke det private nøkkelordet når man beskriver konstruktører – er det spesifikt for oppgaven, et trekk ved utviklingsprosessen eller programmerers preferanser?

Fra et konseptuelt synspunkt kan stamtavlen til gjenstander tillate noen forbud mot forfedre i forhold til etterkommere, men det er vanskelig å si om dette er rimelig logikk, i hvert fall i den generelle sammenhengen.

Objektets levetid

Konseptet med objektorientert programmering er bredere enn funksjonene til PHP-konstruksjonsklassen av den enkle grunn at sistnevnte kun eksisterer når man oppretter en side, gjenoppretter den eller oppretter en annen side på nettstedet.

AJAX deltakelse via Nettleser JavaScript og riktig kode på serveren vil bidra til å forlenge levetiden til objekter, men i alle fall vil det være en begrenset stil.

PHP gir muligheten til å kjøre et skript på serveren når klienten har koblet fra, og å "tillate" klienten tilbake til skriptet den tidligere kjørte, men dette er slett ikke et alternativ når det objektorienterte programmet er implementert i C++ .

I sistnevnte tilfelle kan du bygge et fullverdig system av objekter som vil eksistere "for alltid" mens programmet er oppe og kjører. Dette er imidlertid det eneste et stasjonært programmeringsspråk som C++, C#, Pascal & Delphi kan skryte av. I den dynamiske nettverdenen bygges alt annerledes, lever raskere og oppnår mer.

Fra serialisering til selvoppholdelsesdrift

Du kan finne en historisk begrunnelse for begrepet "serialisering" og utseendet til begrepet "magiske metoder" i hverdagen. Men alt er mye enklere. På nøyaktig samme måte som friheten til C++ skiller seg fra stivheten til C#, skiller serialisering seg fra banale konsepter:

  • skriv et objekt til en streng;
  • lese et objekt fra en streng.

Å omgi det som sies med magi og mytiske magiske metoder er vakkert, klangfullt, men lite praktisk. Informasjonsverdenen er interessant først og fremst fordi alt synlig, hørbart og håndgripelig kan beskrives i enkel og konsistent tekst.

Informasjon har alltid vært, er og vil være en rekke tegn. Det spiller ingen rolle hvilken natur. I de formelle konstruksjonene av programmeringsspråk er karakteren av symboler den samme - en kodingstabell.

Ideen om å gjøre et objekt om til en streng slik at det om nødvendig kan gjenopprettes fra denne strengen uten å miste essensen, er en veldig praktisk idé.

Fra selvoppholdelsesdrift til selvutvikling

Semantikk av PHP-konstruktøren innenfor syntaksen er begrenset, men hvis konstruktøren er utviklet fra en utviklingsposisjon:

  • det er en begynnelse - en helt ny instans er opprettet;
  • Det er Nåværende situasjon- en eksisterende instans opprettes.

Begrensningene til PHP, på grunn av det faktum at systemet med objekter på det eksisterer bare på tidspunktet for sidedannelse, vil bli fjernet av seg selv.

Ved å lage et system med objekter når du oppretter en side, kan den lagres. For enkelhets skyld trenger ikke denne prosessen å kalles serialisering; du kan begrense deg selv til å lagre den nåværende tilstanden (database, filer), og når du trenger å gjenopprette den samme siden eller opprette en annen på samme side, ganske enkelt gjenopprette den nåværende posisjon ting som allerede er dannet.

I denne sammenhengen opprettes et system med objekter bare én gang, og det utvikler seg ganske enkelt under driften av nettstedet. Med et slikt opplegg er det mulig å designe et system av objekter som noe som tilpasser seg skiftende eksistensforhold.

Det selvbevarende objektsystemet "husker" besøkendes handlinger og sidetilstander, og hver gang PHP kjøres, blir det ikke opprettet fra bunnen av, men gjenopprettet til en tidligere tilstand.

Så mye vann har flydd under broen siden PHP erklærte seg selv som OOP-språket. Jeg var ikke i stand til å avklare nøyaktig når, men "Den 13. juli 2004 ble PHP 5 utgitt, drevet av den nye Zend Engine II. PHP 5 inkluderte nye funksjoner som forbedret støtte for objektorientert programmering."
Det vil si at teoretisk sett dukket det opp konstruktører og destruktorer allerede da. Jeg bruker selv versjon 5.3.2, men jeg er overrasket over hva den kan gjøre.

Litt om deg selv. Jeg er en C++ programmerer med 4 års erfaring. Spesialisering - datagrafikk og nettverk. Nemlig opprettelsen av nettspill. Men slike spill trenger en server, og serveren trenger en spillerbase. Og spillerne vil også ha en nettside. "Hvorfor ansette en nettprogrammerer, jeg er ikke dårlig selv. Samtidig skal jeg lære språket.»
Det var det jeg trodde for et halvt år siden, men jeg kan fortsatt ikke forstå det!

Klassisk
Jeg tror mange som jobbet med destruktorer en gang møtte:
PHP Fatal feil: Unntak kastet uten stabelramme i Ukjent på linje 0
Den første reaksjonen er forvirring. Den andre er matt. Og å skyve exit() overalt gir ikke resultater, fordi gjetningen om at unntaket i destruktoren ikke kommer umiddelbart, og hvis det skjer, så er mest sannsynlig kodebasen signifikant.
Svar fra bugs.php.net/bug.php?id=33598
[e-postbeskyttet]:
Å kaste unntak i __desctruct() er ikke tillatt.
Bør dokumenteres..
[e-postbeskyttet]:
Takk for rapporten, og for at du hjelper oss med å gjøre dokumentasjonen vår bedre.
"Forsøk på å kaste et unntak fra en descstructor forårsaker en fatal feil."
Morsom? Personlig liker jeg det egentlig ikke.
Å gjengi en feil med et implisitt unntak er veldig enkelt.
klasse a
{
// ...
offentlig funksjon __destruct()
{
global $_SESSION;
$_SESSION = "Noe informasjon";
}
}
$dummy = ny a();

^Merk at eksplisitte unntak noen ganger fungerer riktig. Jeg vil eksperimentere for å se hvilken effekt det har.

Omvendt rengjøringsrekkefølge
La oss ha følgende kode i et visst omfang (global og ikke veldig mye):
$earth = ny verden();
$vasya = nytt menneske($jord);
Følgelig, i koden til en persons konstruktør, blir han brakt i kontakt med verden. (Det antas at uten verden vil ikke Vasya eksistere, la oss forkaste filosofien, vi bør raskt avslutte prosjektet.)
Vel, i destruktorkoden ligger Vasya ala $this->my_world->RemoveHumanFromWorld($this), der RemoveAllMyStuff, CalculateKarma og så videre kalles. (Anta at vi ikke har en lenke til Vasya i vår verden, siden dette ikke var nødvendig innenfor oppgavens omfang)
Hva gjør PHP når det går utenfor scope? Ødelegger verden og krasjer med feilen "Fatal error: Call to a member function RemoveHumanFromWorld() på et ikke-objekt i /home/god/my_projects/earth/creatures/reasonable/homo_sapiens.php på linje 1956."
(Det er derfor, forresten, verden ble skrevet i C++, fordi Gud trenger den ikke for å kjøre på noe univers. Virtuelt rom med en søppelsamler. Ha Ha.)
Svar fra bugs.php.net/bug.php?id=36759
[e-postbeskyttet]
Rettet i CVS HEAD og PHP_5_2.
Jeg skulle ønske jeg kunne finne denne Dmitry og stikke ham med nesen som på bildet. Jeg vet ikke hvordan det er der siste versjoner, jeg har ikke oppdatert ennå, men det er relevant i 5.3.
Skriptavslutning - unntak
Å, det kan skrives så mye om dette. Globale variabler (ala sessions) slutter å være gyldige, tilgang til filsystem er avskåret. Og generelt, slik jeg forstår det, er det ikke garantert korrekt drift av skriptet. Så Gud forby deg å gjøre noe i ødeleggelsen av et globalt objekt...
Men la oss utelate det. Dokumentasjonen for PHP 5.1 og tidligere (jeg finner ikke strofen og verset) sier: "Destructor-metoden vil bli kalt så snart det ikke er andre referanser til et bestemt objekt," som i prinsippet er logisk for en språk uten et strengt krav til slettekonstruksjonen (lat. unset).
Etter feilrapporten bugs.php.net/bug.php?id=38572
Dokumentasjonen er endret "Destruktormetoden vil bli kalt så snart det ikke er andre referanser til et bestemt objekt, eller i hvilken som helst rekkefølge under avslutningssekvensen"
Komfortabel? For meg - ikke veldig mye.
Kun direktelenker
La, i henhold til språkets logikk, objekt $a slettes før $b.
Men la $b-objektet lagre en lenke til $a->some_data-feltet.
Deretter, logisk sett, bør objekt $b slettes tidligere. Akk, dette er ikke tilfelle i PHP. Jeg fant ikke en slik feil, men situasjonen er spesifikk (og tør jeg si eksepsjonell). Det unngås av en svak oppdatering opp til lenken til $a, det er tolerabelt og jeg rapporterte det ikke.
Deadlock i PHP-stil
$a->ref = $b;
$b->ref = $a;
På et tidspunkt var jeg interessert i hvordan PHP ville takle kryssreferanser. Vil det fryse? Vil du få feilmeldingen "du kan ikke forlate scope" og hvordan vil det høres ut på engelsk? Akk, drivhuset viste at alle variabler vil eksistere til slutten, til det kommer, som de sier, "eller i hvilken som helst rekkefølge under avstengningssekvensen"
Konklusjon
dette øyeblikket alt jeg husket. Eller kanskje alt jeg har møtt. Men jeg fikk inntrykk av at destruktorer i PHP er en krykke, så mest sannsynlig vil jeg komme over det igjen snart.
Det ser ut til at fremtiden til OOP-webprogrammering ligger i C++-tolken, og kanskje den vil være klar. Kanskje vil noen en dag bestemme seg for å endre C++, legge til standardkonstruksjoner slik at det blir nettorientert. Men så langt har jeg ikke funnet noen alternativer.

Destruktor PHP klasse OOP er spesiell funksjon (som tilhører en gruppe metoder kjent som magiske metoder), som automatisk kalles opp når et objekt slettes. Destruktoren godtar ingen parametere. Konseptet med en destruktor ble introdusert i PHP5, som implementerer en fullverdig objektorientert modell. En barneklasse kan arve en destruktor fra en overordnet klasse hvis den ikke implementerer selve destruktoren.

Når et objekt er opprettet, kan PHP-konstruktørfunksjonen kalles for å initialisere medlemsvariabler. Destruktoren utfører den motsatte funksjonen; når et objekt slettes, frigjør det minne og serverressurser. Destruktoren er også viktig funksjon, siden serverressursene er begrenset, og dusinvis av applikasjoner fra forskjellige individuelle nettsteder kjører på den samtidig.

Derfor er det alltid en god idé å bruke en PHP-destruktor. For å sikre en tilkobling til en database kan det for eksempel være lurt å lukke kontakten umiddelbart. I dette tilfellet kan en destruktor være veldig nyttig.

En ting å huske på er at, i motsetning til noen andre programmeringsspråk, har OOP PHP en søppelsamler som fjerner objekter når de ikke lenger brukes. Men hvis vi ønsker å slette et objekt eksplisitt, er PHPs destruktor egnet for dette.

PHP-søppelsamleren fjerner ubrukte objekter, men dette kan ta litt tid og inntil da vil det ubrukte objektet ha ressurser tilordnet det. Ved å bruke en destruktor sikrer vi at ingen ressurser går til spille, og det forbedrer effektiviteten til applikasjoner og nettsteder. Hvis vi snakker om ett objekt, vil bruk av en destruktor ikke gi merkbare endringer.

Men hvis applikasjonen er kompleks og bruker mange objekter, kan bruk av en PHP-destruktor ha en betydelig effekt.

PHP destruktor syntaks

I følge PHP OOP grunnleggende, når du erklærer en destruktor, brukes den magiske metodenotasjonen - to ledende understrekinger og nøkkelordet destruct:

En destruktor i PHP kan ikke kalles eksplisitt, akkurat som vi ikke kan kalle en konstruktør eksplisitt:

$myobject -> __destruct(); - umulig

En annen viktig poeng Angående destruktoren: akkurat som konstruktøren kalles den for et objekt bare én gang - på det tidspunktet objektet slettes.

PHP destructor eksempel

Nedenfor er et enkelt eksempel på en PHP-destruktor:

offentlig funksjon __destruct() (skriv ut "($this->Name) er ødelagt...n"; )

Denne destruktoren skriver ut en melding som indikerer at objektet er slettet. Vi kan lukke socket-tilkoblingen til databasen, men jeg skriver ikke denne koden. Faktisk vil hele prosessen være mer komplisert.

Jeg håper du forstår generelt prinsipp destructor fungerer:

offentlig funksjon __destruct() ( Plasser KJØRBAR KODE i parentes. )

Et annet OOP PHP-eksempel på komplett destruktor- og konstruktørkode:

navn = "Bil"; ) funksjon __destruct() ( skriv ut "Ødelegger " . $this->name . "n"; ) ) $obj = ny bil(); ?>

I PHP OOP kalles destruktoren bare én gang. Det beste alternativet er å bruke Parent::_destruct() . Men den overordnede destruktoren bør tilkalles etter stedet hvor destruktorkoden er plassert for å sikre at objektet ikke blir ødelagt før det har blitt brukt i applikasjonen.

Se eksempelet nedenfor:

offentlig funksjon __destruct() (skriv ut "($this->Name) er ødelagt...n"; overordnet:: _destruct(); )

Oversettelsen av artikkelen "PHP destructor" ble utarbeidet av det vennlige prosjektteamet.

Bra dårlig

Velkommen til den andre leksjonen i serien om OOP. I den første artikkelen lærte du det grunnleggende om OOP i PHP, inkludert begrepene klasser, metoder, felt og objekter. Du har også lært hvordan du lager en enkel klasse og implementerer den.

I denne artikkelen vil du lære enda mer om klassemetoder og -felt. Dette vil gi deg godt grunnlag, for å begynne å lære mer profesjonelle teknikker som for eksempel arv.

Her er en liste over hva jeg vil fortelle deg om i denne artikkelen:

  • Konstruktører og destruktorer, som lar deg tilordne spesifikke handlinger til et objekt når det opprettes og slettes;
  • Statiske felt og metoder er de feltene og metodene som ikke er knyttet til spesifikke objekter i en klasse;
  • Klassekonstanter, nyttige for å lagre faste verdier relatert til en spesifikk klasse;
  • En eksplisitt typeindikasjon som brukes til å sette begrensninger på hvilke typer parametere som kan overføres til en bestemt metode;
  • Spesielle metoder __get() og __set(), som brukes til å sette og lese verdiene til klassefelt;
  • En spesiell metode __call() som brukes til å kalle en klassemetode.

Er du klar? Så fortsett!

Konstruktører og destruktorer

Noen ganger er det behov for å utføre noen handlinger samtidig med opprettelsen av et objekt. For eksempel kan det hende du må angi verdier for feltene til et objekt umiddelbart etter at det er opprettet, eller initialisere dem med verdier fra databasen.

I likhet med dette kan det hende du må utføre visse handlinger for å fjerne et objekt fra minnet, for eksempel å slette objekter som er avhengige av den som slettes, lukke databasetilkoblingen eller lukke filer.

Merk: hvordan sletter jeg et objekt? PHP fjerner automatisk et objekt fra minnet når det ikke er noen variabler igjen som peker til det. For eksempel hvis du oppretter nytt objekt og lagre den i $myObject-variabelen og deretter slette den ved å bruke unset($myObject)-metoden, så vil selve objektet også bli slettet. Dessuten, hvis du opprettet en lokal variabel i en funksjon, vil den (sammen med objektet) bli slettet når funksjonen avsluttes.

PHP har to spesielle metoder som kan brukes til å utføre spesifikke handlinger for å opprette og slette objekter:

  • Konstruktøren kalles opp umiddelbart etter at du har laget objektet;
  • Destruktoren kalles strengt før objektet fjernes fra minnet.

Jobber med konstruktører

Bruk konstruktører til å spesifisere handlingene som skal utføres for å lage et objekt i en klasse. Disse handlingene kan inkludere initialisering av klassefelt, åpning av filer, lesing av data.

For å lage en konstruktør, legg til en spesiell metode __construct() til klassen din (to understreker før ordet construct). PHP vil automatisk kalle denne metoden når du implementerer klassen din, det vil si når du oppretter et objekt av den klassen.

Her er et eksempel på en konstruktør:

Klasse MyClass ( offentlig funksjon __construct() ( ekko "Jeg er nettopp opprettet!"; ) ) $myObject = new MyClass(); // vil vise "Jeg"har nettopp blitt opprettet!"

MyClass-klassen har en konstruktør som skriver ut strengen "I"ve just been created!" til siden. Siste linje kode oppretter et nytt klasseobjekt MyClass. Når dette skjer, kaller PHP automatisk konstruktøren og meldingen vises i nettleseren. Nå i praksis - initialisering av klassefelt:

Klassemedlem ( privat $username; privat $location; privat $homepage; offentlig funksjon __construct($username, $location, $homepage) ( $this->username = $username; $this->location = $location; $this- >hjemmeside = $hjemmeside; ) offentlig funksjon showProfile() ( echo "

"; ekko "
Brukernavn:
$this->brukernavn
"; ekko "
Plassering:
$this->location
"; ekko "
Hjemmeside:
$this->hjemmesiden
"; ekko "
"; ) ) $aMember = nytt medlem("fred", "Chicago", "http://example.com/"); $aMember->showProfile();

Dette skriptet vil vise følgende på siden:

Brukernavn: fred Sted: Chicago Hjemmeside: http://example.com/

Medlemsklassen vår har tre felt og en konstruktør som tar 3 verdier som parametere - en for hvert felt. Konstruktøren vil tilordne verdiene som mottas som argumenter til objektets felt. Klassen har også en metode for å vise verdiene til et objekts felt på siden.

Deretter oppretter koden et objekt av Member-klassen, som vi sender 3 verdier "fred", "Chicago" og "http://example.com/", siden konstruktøren tar nøyaktig 3 parametere. Konstruktøren skriver disse verdiene til feltene til det opprettede objektet. Til slutt kalles showProfile()-metoden på det opprettede objektet for å vise de resulterende verdiene.

Jobber med destruktorer

Bruk en destruktor når et objekt fjernes fra minnet. Du må kanskje lagre objektet i databasen, lukk åpne filer, som samhandlet med objektet. For å lage en destruktor, legg til __destruct()-metoden til klassen. Den kalles opp rett før objektet slettes automatisk. Her er et enkelt eksempel:

Klasse MyClass ( offentlig funksjon __destruct() ( ekko "Jeg er i ferd med å forsvinne - bye bye!"; // (tøm minne) ) ) $myObject = new MyClass(); unset($myObject); // viser "I "Jeg er i ferd med å forsvinne - bye bye!"

Vi har laget en enkel destruktor som viser en melding på siden. Vi opprettet deretter et objekt av klassen vår og slettet det umiddelbart ved å kalle unset()-metoden på variabelen som refererer til objektet. Rett før du sletter objektet, ble destruktoren tilkalt, som viste meldingen "Jeg er i ferd med å forsvinne - bye bye!" i nettleseren.

Merk: i motsetning til konstruktører kan du ikke sende noen parametere til destruktorer.

Destruktoren kalles også når skriptet avsluttes, siden alle objekter og variabler slettes når metoden avsluttes. Så, følgende kode vil også kalle destruktoren:

Klasse MyClass ( offentlig funksjon __destruct() ( ekko "Jeg er i ferd med å forsvinne - bye bye!"; // (tøm minne) ) ) $myObject = new MyClass(); exit; // viser "I"m about to forsvinn - bye bye!"

Hvis skriptet slutter å kjøre på grunn av en feil, vil destruktoren også bli kalt.

Merk: når du oppretter objekter av en etterkommerklasse, kalles ikke konstruktørene til den overordnede klassen automatisk. Det er kun konstruktøren til selve arvingen som blir tilkalt. Imidlertid kan du kalle foreldrenes konstruktør fra en underklasse som dette:

overordnet::__construct(). Det samme gjelder destruktorer. Du kan kalle foreldrenes destruktor slik: parent:__destruct(). Jeg skal fortelle deg om foreldre- og barneklasser i neste leksjon om arv.

Statiske klassefelt

Vi dekket statiske variabler i artikkelen PHP Variable Scope: All Du trengerå vite. Som en vanlig lokal variabel, er en statisk variabel bare tilgjengelig innenfor en funksjon. Men i motsetning til vanlige lokale variabler, beholder statiske variabler verdiene sine mellom funksjonskall.

Statiske klassefelt fungerer etter samme prinsipp. Et statisk klassefelt er knyttet til klassen, men det beholder sin verdi gjennom hele skriptet. Sammenlign dette med vanlige felt: de er knyttet til et bestemt objekt, og de går tapt når det objektet slettes.

Statiske felt er nyttige i tilfeller der du trenger å lagre en spesifikk verdi som gjelder en hel klasse i stedet for et enkelt objekt. De ligner globale klassevariabler.

For å lage en statisk variabel, legg til det statiske nøkkelordet i definisjonen:

Klasse MyClass (offentlig statisk $myProperty;)

Her er et eksempel på hvordan statiske variabler fungerer:

Klassemedlem (privat $username; offentlig statisk $numMembers = 0; offentlig funksjon __construct($username) ( $this->username = $username; self::$numMembers++; ) ) echo Member::$numMembers . "
"; // vil vise "0" $aMember = nytt medlem("fred"); echo Member::$numMembers . "
"; // vil vise "1" $anotherMember = nytt medlem("mary"); echo Member::$numMembers . "
"; // viser "2"

Det er noen interessante ting, så la oss ta en titt på dette manuset:

  • Medlemsklassen har to felt: det private feltet $brukernavn og det statiske feltet $numMembers, som i utgangspunktet er satt til 0;
  • Konstruktøren tar argumentet $username som en parameter og setter feltet til det nyopprettede objektet til verdien av denne parameteren. Samtidig øker den verdien til $numMembers-feltet, og gjør det klart at antallet objekter i klassen vår har økt med 1.

Merk at konstruktøren får tilgang til det statiske feltet slik: self::$numMembers. Selvsøkeordet ligner på $this, som vi så på i forrige leksjon. Mens $this refererer til gjeldende objekt, refererer self til gjeldende klasse. Mens du bruker -> for å få tilgang til feltene og metodene til et objekt, bruker du i dette tilfellet :: for å få tilgang til feltene og metodene til en klasse.

  • Til slutt oppretter skriptet flere objekter av Member-klassen og viser nummeret deres på siden, dvs. verdien av den statiske variabelen $numMembers. Merk at denne variabelen beholder sin verdi gjennom hele skriptet, til tross for klasseobjekter.

Så, for å få tilgang til et statisk felt i en klasse, bruk ::-operatoren. Her kan vi ikke bruke self-nøkkelordet fordi koden er utenfor klassen, så vi skriver klassenavnet, deretter ::, og deretter feltnavnet (Member::$numMembers). Innenfor konstruktøren må du også bruke nettopp en slik struktur, og ikke selv.

Merk: det var enkelt for skriptet vårt å få tilgang til klassefeltet $numMembers før det første objektet i denne klassen ble opprettet. Det er ikke nødvendig å lage objekter av en klasse for å bruke dens statiske felt.

Statiske metoder

Sammen med statiske klassefelt kan du også lage statiske metoder. Statiske metoder, som felt, er assosiert med en klasse, men det er ikke nødvendig å opprette et objekt av klassen som skal kalles statisk metode. Dette gjør slike metoder nyttige hvis du trenger en klasse som ikke fungerer på ekte objekter.

For å lage en statisk metode må du legge til det statiske nøkkelordet i erklæringen:

Klasse MyClass ( offentlig statisk funksjon myMethod() ( // (handlinger) ) )

Vårt forrige eksempel på statiske felt var det statiske feltet $numMembers. Å gjøre felt private og metoder for å få tilgang til dem offentlige er god trening. La oss gjøre vårt statiske felt privat og skrive en offentlig statisk metode for å få verdien av det gitte feltet:

Klassemedlem ( privat $brukernavn; privat statisk $numMembers = 0; offentlig funksjon __construct($brukernavn) ( $this->brukernavn = $brukernavn; self::$numMembers++; ) offentlig statisk funksjon getNumMembers() ( return self::$ numMembers; ) ) echo Member::getNumMembers() . "
"; // vil vise "0" $aMember = nytt medlem("fred"); echo Member::getNumMembers() . "
"; // vil vise "1" $anotherMember = nytt medlem("mary"); echo Member::getNumMembers() . "
"; // viser "2"

Her har vi laget en statisk metode getNumMembers() som returnerer verdien til det statiske feltet $numMembers. Vi gjorde også dette feltet privat slik at verdien ikke kan hentes utenfra.

Vi endret også kallekoden til å bruke getNumMembers()-metoden for å få verdien av $numMembers-feltet. Vær oppmerksom på at du kan ringe denne metoden uten å lage et klasseobjekt fordi metoden er statisk.

Klassekonstanter

Konstanter lar deg angi en global verdi for hele koden din. Denne verdien er fast og kan ikke endres. Klassekonstanter ligner på vanlige konstanter. Hovedforskjellen er at i tillegg til at en klassekonstant er global, kan den nås fra klassen den er definert i. Klassekonstanter er nyttige i tilfeller der du trenger å lagre spesifikke verdier som tilhører en bestemt klasse.

Du kan definere en klassekonstant ved å bruke nøkkelordet const. For eksempel:

Klasse MyClass ( const CONSTANT_NAME = verdi; )

Du kan deretter få tilgang til en klassekonstant gjennom klassenavnet og ::-operatoren. For eksempel slik:

Min klasse::CONSTANT_NAME

Merk: Som med statiske felt og metoder, kan du få tilgang til en konstant ved å bruke selvnøkkelordet.

La oss se på klassekonstanter med et eksempel. La oss legge til konstanter til medlemsklassen som vil lagre verdiene til rollen deres (deltaker, moderator eller administrator). Ved å bruke konstanter i stedet for vanlige numeriske verdier, gjorde vi koden mer lesbar. Her er manuset:

Klassemedlem ( const MEMBER = 1; const MODERATOR = 2; const ADMINISTRATOR = 3; privat $username; privat $level; offentlig funksjon __construct($username, $level) ( $this->username = $username; $this-> level = $level; ) offentlig funksjon getBrukernavn() ( return $this->brukernavn; ) offentlig funksjon getLevel() ( if ($this->level == self::MEMBER) returner "et medlem"; if ($this ->nivå == selv::MODERATOR) returner "en moderator"; hvis ($this->level == selv::ADMINISTRATOR) returnerer "en administrator"; returner "ukjent"; ) ) $aMember = nytt medlem(" fred", Medlem::MEMBER); $anotherMember = nytt medlem("mary", Member::ADMINISTRATOR); echo $aMember->getUsername() . "er". $aMember->getLevel() . "
"; // vil vise "fred er et medlem" echo $anotherMember->getUsername() . " er " . $anotherMember->getLevel() . "
"; // viser "mary er administrator"

Vi laget tre klassekonstanter: MEMBER, MODERATOR og ADMINISTRATOR, og ga dem henholdsvis verdiene 1, 2 og 3. Deretter legger vi til et $level-felt for å lagre roller og endrer konstruktøren litt for å initialisere dette feltet også. Klassen la også til en annen metode - getLevel(), som returnerer en spesifikk melding avhengig av verdien til $level-feltet. Den sammenligner denne verdien med hver av klassekonstantene og returnerer den ønskede strengen.

Skriptet lager flere objekter med forskjellige roller. For å tildele roller til objekter er det klassekonstanter som brukes, og ikke enkle numeriske verdier. Deretter kalles metodene getUsername() og getLevel() på hvert objekt, og resultatene vises på siden.

Eksplisitt spesifisere funksjonsargumenttyper

I PHP trenger du ikke spesifisere datatyper, så du trenger ikke å bekymre deg for hvilke argumenter du sender til metoder. For eksempel kan du trygt sende en numerisk verdi til strlen()-funksjonen, som beregner lengden på en streng. PHP vil først konvertere tallet til en streng og deretter returnere lengden:

Ekko strlen(123); // vis "3"

Noen ganger er det nyttig å spesifisere typen eksplisitt, men det kan føre til feil som er vanskelige å håndtere, spesielt hvis du jobber med komplekse datatyper som objekter.

For eksempel

Se på denne koden:

Klassemedlem ( privat $brukernavn; offentlig funksjon __construct($brukernavn) ( $this->brukernavn = $brukernavn; ) offentlig funksjon getUsername() ( return $this->brukernavn; ) ) klasse Emne (privat $medlem; privat $subject ; offentlig funksjon __construct($medlem, $emne) ( $this->member = $medlem; $this->subject = $subject; ) offentlig funksjon getUsername() (retur $this->member->getUsername(); ) ) $aMember = nytt medlem("fred"); $aTopic = nytt emne($aMember, "Hei alle sammen!"); echo $aTopic->getUsername(); // vil vise "fred"

Dette skriptet fungerer slik:

  • Vi lager medlemsklassen vår med et $username-felt, en konstruktør og en getUsername()-metode;
  • Vi oppretter også en emneklasse for å administrere forumartikler. Den har to felt: $member og $subject. $member er et objekt av Member-klassen, dette vil være forfatteren av artikkelen. $subject-feltet er emnet for artikkelen.
  • Topic-klassen inneholder også en konstruktør som tar et Member-objekt og en streng som representerer emnet for artikkelen. Den initialiserer klassefeltene med disse verdiene. Den har også en getUsername()-metode, som returnerer navnet på forummedlemmet. Dette oppnås ved å kalle opp getUsername()-metoden til Member-objektet.
  • Til slutt lager vi et objekt av Member-klassen med feltverdien brukernavn "fred". Deretter lager vi et objekt av klassens emne, passerer det Fred og emnet for artikkelen "Hei alle sammen!". Til slutt kaller vi getUsername()-metoden til Topic-klassen og viser brukernavnet ("fred") på siden.

Alt dette er veldig bra, men...

La oss gjøre det bedre!

La oss legge til denne kodebiten på slutten:

Class Widget ( privat $colour; offentlig funksjon __construct($colour) ( $this->colour = $colour; ) offentlig funksjon getColour() ( return $this->colour; ) ) $aWidget = new Widget("blue") ; $anotherTopic = nytt emne($aWidget, "Oops!"); // vil vise "Fatal error: Call to undefined method Widget::getUsername()" echo $anotherTopic->getUsername();

Her lager vi en Widget-klasse med et $colour-felt, en konstruktør og en getColour()-metode som returnerer fargen til widgeten.

Vi vil da lage et objekt av denne klassen, etterfulgt av et Topic-objekt med argumentet $aWidget, når vi faktisk trenger å passere forfatteren av artikkelen, dvs. Medlemsklasseobjekt.

La oss nå prøve å kalle getUsername()-metoden til Topic-klassen. Denne metoden kaller getUsername()-metoden til Widget-klassen. Og siden det ikke er noen slik metode i denne klassen, får vi en feilmelding:

Fatal feil: Anrop til udefinert metode Widget::getUsername()

Problemet er at årsaken til feilen ikke er så lett å forstå. Hvorfor leter emneobjektet etter en metode i Widget-klassen og ikke medlem? I et komplekst klassehierarki vil det være svært vanskelig å finne en vei ut av denne typen situasjoner.

Vi gir et hint

Det ville være bedre å begrense emnekonstruktøren til å akseptere argumenter slik at den bare kan akseptere medlemsobjekter som sin første parameter, og dermed forhindre fatale feil.

Dette er nøyaktig hva eksplisitt typespesifikasjon gjør. For å eksplisitt spesifisere typen til en parameter, sett inn klassenavnet før argumentnavnet i metodeerklæringen:

Funksjon myMethod(Klassenavn $objekt) ( // (handlinger) )

La oss justere konstruktøren for emneklassen slik at den bare godtar medlem:

Klasseemne ( privat $medlem; privat $emne; offentlig funksjon __construct(Medlem $medlem, $emne) ( $this->member = $medlem; $this->subject = $subject; ) offentlig funksjon getUsername() ( return $ this->member->getUsername(); ) )

La oss nå prøve å lage et emneobjekt igjen, og gi det en widget:

$aWidget = ny widget("blå"); $anotherTopic = nytt emne($aWidget, "Oops!");

Denne gangen vil PHP vise en spesifikk feil:

Fangbar fatal feil: Argument 1 sendt til Topic::__construct() må være en forekomst av Member, forekomst av Widget gitt, kalt inn script.php på linje 55 og definert i script.php på linje 24

Dette problemet vil være mye lettere å håndtere, siden vi vet nøyaktig hva årsaken til feilen er - vi prøvde å sende en parameter til konstruktøren av feil type. Feilmeldingen viser til og med de nøyaktige kodelinjene der metoden som forårsaket feilen ble kalt.

Initialisere og lese klassefeltverdier ved å bruke __get() og __set()

Som du allerede vet, inneholder klasser vanligvis felt:

Klasse MyClass ( offentlig $aProperty; offentlig $anotherProperty; )

Hvis klassens felt er offentlige, kan du få tilgang til dem ved å bruke ->-operatoren:

$myObject = ny MyClass; $myObject->aProperty = "hei";

Imidlertid lar PHP deg lage "virtuelle" felt som faktisk ikke er i klassen, men som kan nås via ->-operatøren. De kan være nyttige i følgende tilfeller:

  • Når du har mange felt og du vil lage en matrise for dem for ikke å deklarere hvert felt separat;
  • Når du trenger å lagre et felt utenfor et objekt, for eksempel i et annet objekt, eller til og med i en fil eller database;
  • Når du trenger å beregne feltverdier i farten, i stedet for å lagre verdiene deres et sted.

For å lage slike "virtuelle" felt, må du legge til et par magiske metoder til klassen:

  • __get($propName) kalles opp automatisk når man prøver å lese verdien av det "usynlige" feltet $propName;
  • __set($propName,$propValue) kalles opp automatisk når man prøver å sette det "usynlige" feltet $propNavn til $propValue.

"Usynlig" i i denne sammenhengen Dette betyr at i denne delen av koden kan du ikke få direkte tilgang til disse feltene. For eksempel hvis et slikt felt ikke finnes i klassen i det hele tatt, eller om det finnes, men det er privat, og det ikke er tilgang til et slikt felt utenfor klassen.

La oss gå videre til praksis. La oss endre medlemsklassen vår slik at det i tillegg til $username-feltet er andre tilfeldige felt som vil bli lagret i $data-arrayen:

Klassemedlem ( privat $brukernavn; privat $data = array(); offentlig funksjon __get($property) (if ($property == "brukernavn") ( return $this->brukernavn; ) else (if (array_key_exists($property) , $this->data)) ( return $this->data[$property]; ) else (retur null; ) ) public function __set($property, $value) (if ($property == "brukernavn" ) ( $this->brukernavn = $value; ) else ( $this->data[$property] = $value; ) ) ) $aMember = nytt medlem(); $aMember->brukernavn = "fred"; $aMember->location = "San Francisco"; echo $aMember->brukernavn . "
"; // viser "fred" echo $aMember->location . "
"; // viser "San Francisco"

Slik fungerer det:

  • Medlemsklassen har et konstant felt privat $brukernavn og en privat array $data for lagring av tilfeldige "virtuelle" felt;
  • __get()-metoden tar en enkelt parameter $property - navnet på feltet hvis verdi skal returneres. Hvis $property = "brukernavn", vil metoden returnere verdien av $brukernavn-feltet. Ellers vil metoden sjekke om en slik $property forekommer i nøklene til $datamatrisen. Hvis en slik nøkkel blir funnet, vil den returnere verdien av dette feltet, ellers - null.
  • __set()-metoden tar 2 parametere: $property - navnet på feltet som må initialiseres, og $value - verdien som må angis for dette feltet. Hvis $property = "brukernavn", initialiserer metoden $username-feltet med verdien fra $value-parameteren. Ellers legger du $property-nøkkelen med verdien $value til $datamatrisen.
  • Etter å ha opprettet Member-klassen, lager vi et objekt av denne klassen og initialiserer $username-feltet med verdien "fred". Dette kaller __set()-metoden, som vil sette $username-verdien til objektet. Deretter setter vi verdien av $location-feltet til "San Francisco". Siden et slikt felt ikke eksisterer i objektet, skriver metoden det til $data-matrisen.
  • På slutten tar vi ut verdiene til $username og $location og viser dem på siden. __get()-metoden henter den faktiske $username-verdien fra det eksisterende $username-feltet og $location-verdien fra $datamatrisen.

Som du kan se, ved å bruke metodene __get() og __set() har vi laget en klasse som kan inneholde både ekte felt og alle "virtuelle" felt. Fra et kodestykke hvor en verdi er satt for et bestemt felt, er det ikke nødvendig å vite om et slikt felt finnes eller ikke i objektet. Ved å bruke den vanlige ->-operatoren kan du sette en verdi til et felt eller lese det.

Eksemplet viser også hvordan du enkelt kan lage metoder, kalt "getters" og "settere", for å få tilgang til private felt. Vi trenger ikke lage separate få metoder Username() og setUsername() for å få tilgang til det private $username-feltet. I stedet opprettet vi __get() og __set() metoder for å manipulere dette feltet. Dette betyr at vi kun trenger 2 metoder totalt, i stedet for 2 metoder for hvert privat felt.

Merk: Et ord om innkapsling. Å bruke private klassefelt i kombinasjon med gettere og settere er bedre enn å bruke offentlige variabler. Gettere og settere kan i tillegg behandle data gitt til og fra et objekts felt, for eksempel å sjekke om en verdi er i riktig format eller konvertere den til ønsket format. Gettere og settere skjuler også detaljene om hvordan feltene til en klasse er implementert, noe som gjør det lettere å modifisere det interne i en klasse fordi du ikke trenger å omskrive koden som opererer på objekter i den klassen. For eksempel vil du plutselig lagre verdien av et felt i en database. Hvis du allerede hadde gettere og settere, er alt du trenger å gjøre å skrive dem om. EN ringekode vil forbli den samme. Denne teknikken kalles innkapsling, og det er en av hovedfordelene med OOP.

Overbelastningsmetoder med __call()

Gettere og settere brukes til å nekte tilgang til private variabler. I samme retning brukes __call()-metoden for å nekte tilgang til private metoder. Når koden kaller en klassemetode som enten ikke eksisterer eller ikke er tilgjengelig, kalles __call()-metoden automatisk. Her generell syntaks metode:

Offentlig funksjon __call($methodName, $arguments) ( // (handlinger) )

Når det gjøres et forsøk på å kalle en utilgjengelig klassemetode, kaller PHP automatisk __call()-metoden, som den sender en streng til - navnet på den kalte metoden og en liste over beståtte parametere i en matrise. Din __call()-metode vil da måtte håndtere anropet på en bestemt måte og returnere verdier om nødvendig.

__call()-metoden er nyttig i situasjoner der du trenger å overføre funksjonaliteten til en klasse til en annen klasse. Her er et enkelt eksempel:

Klassemedlem ( privat $brukernavn; offentlig funksjon __construct($brukernavn) ( $this->brukernavn = $brukernavn; ) offentlig funksjon getUsername() ( return $this->brukernavn; ) ) klasse Emne (privat $medlem; privat $subject ; offentlig funksjon __construct($medlem, $emne) ( $this->member = $medlem; $this->subject = $emne; ) offentlig funksjon getSubject() (retur $this->subject; ) offentlig funksjon __call($ metode, $arguments) ( return $this->member->$method($arguments); ) ) $aMember = nytt medlem("fred"); $aTopic = nytt emne($aMember, "Hei alle sammen!"); echo $aTopic->getSubject() . "
"; // vil vise "Hei alle sammen!" echo $aTopic->getUsername() . "
"; // viser "fred"

Dette eksemplet ligner det som er gitt i avsnittet om eksplisitt spesifisering av typer. Vi har en Medlemsklasse med et felt $brukernavn og en Emneklasse med et felt - et objekt av Medlemsklassen (forfatter av artikkelen) og et felt $subject - artikkelens emne. Topic-klassen inneholder en getSubject()-metode for å få emnet til en artikkel, men den har ikke en metode som returnerer navnet på forfatteren av artikkelen. I stedet har den en __call()-metode, som kaller en ikke-eksisterende metode og sender argumenter til Member-klassemetoden.

Når koden din kaller $aTopic->getUsername()-metoden, forstår PHP at ingen slik metode eksisterer i Topic-klassen. Derfor kalles __call()-metoden, som igjen kaller getUsername()-metoden til Member-klassen. Denne metoden returnerer forfatterens navn til __call()-metoden, som sender den resulterende verdien til anropskoden.

Merk: PHP har andre metoder som håndterer overbelastning, for eksempel __isset(), __unset() og __callStatic().

Konklusjon

I denne leksjonen utdypet du kunnskapen din om OOP i PHP ved å se på felt og metoder mer detaljert. Du har studert:

  • Konstruktører og destruktorer, nyttige for å initialisere felt og tømme minne etter at objekter er slettet;
  • Statiske felt og metoder som opererer på klassenivå i stedet for på objektnivå;
  • Klassekonstanter, nyttige for å lagre faste verdier som trengs på klassenivå;
  • Eksplisitt indikasjon av typer, som du kan begrense typene argumenter som sendes til metoden;
  • De magiske metodene __get(), __set() og __call(), som brukes for å få tilgang til private felt og metoder i en klasse. Implementering av disse metodene lar deg lage "virtuelle" felt og metoder som ikke finnes i klassen, men som samtidig kan kalles.

Med kunnskapen du har fått i denne og de tidligere opplæringene, kan du begynne å skrive OOP. Men dette er bare begynnelsen! I neste leksjon skal vi snakke om kraften til OOP - klassenes evne til å arve funksjonalitet fra andre klasser.

God programmering!

Ny objektorientert modell i PHP5

Da Zeev Suraski la til objektorientert (OO) syntaks til PHP 3, kunne det tenkes på som "syntaktisk sukker for tilgang til samlinger". Den objektorienterte modellen fikk støtte for arv og tillot en klasse (og objekt) å kombinere metoder og egenskaper, men ikke noe mer. Da Ziv og Andi skrev om motoren for PHP 4, var det en helt ny motor, mye raskere, mye mer stabil og med mange flere funksjoner. Endringene påvirket imidlertid praktisk talt ikke OO-modellen, opprinnelig introdusert i PHP 3.

Selv om objektmodellen hadde alvorlige begrensninger, ble den mye brukt, ofte i svært store applikasjoner skrevet i PHP. Denne triumferende marsjen av OOP-paradigmet, selv så begrenset i PHP 4, førte til det faktum at endringer objektmodell ble sentral i den nye PHP-utgivelsen - PHP5.

Hva var begrensningene i PHP 3 og 4? Den største begrensningen (som førte til alle andre begrensninger) var det faktum at semantikken til en objektforekomst var den samme som for native typer. Hvordan påvirket dette utviklerne egentlig? Når du tilordnet en variabel (som peker til et objekt) til en annen variabel, ble det opprettet en kopi av objektet. Ikke bare påvirket dette ytelsen, men det førte vanligvis til feil i applikasjonen fordi mange utviklere trodde at begge variablene ville peke til samme objekt. Og de pekte på forskjellige kopier av det samme objektet, så når vi endret ett objekt, endret vi ikke det andre. Her er et eksempel:

klasse person(
var $navn ;
funksjon getName()(
returner $this -> navn ;
}
funksjonssettNavn ($navn) (
$this -> navn = $navn ;
}
funksjon Person ($name) (
$this -> setName ($name);
}
}

Funksjon changeName ($person, $name) (
$person -> setName ($name);
}

$person = ny person("Andi");
changeName($person, "Stig");
print $person -> getName();
?>

I PHP 4 vil denne koden sende ut "Andi". Årsaken er at vi passerer et objekt $person inn i en funksjon endre navn() etter verdi, ikke etter referanse, så objektet $person vil bli kopiert, og endre navn() vil allerede fungere med en kopi av objektet $person.

Denne oppførselen er ikke intuitiv. Faktisk forventet mange utviklere Java-lignende oppførsel. I Java er variabler faktisk pekere til et objekt, og derfor vil duplisering kopiere pekeren, ikke selve objektet.

Det var to typer utviklere: de som visste om dette problemet, og de som ikke gjorde det. Sistnevnte møtte vanligvis ikke dette problemet fordi koden deres var skrevet på en slik måte at det var likegyldig om et slikt problem eksisterte eller ikke. Selvfølgelig tilbrakte noen av disse utviklerne søvnløse netter i "spennende" søk etter "overnaturlige" feil. Den første gruppen hadde også et problem fordi de manuelt måtte definere overføringen av et objekt ved referanse, og forhindret motoren i å kopiere objektene, og koden var full av mange " & ".

Den gamle objektmodellen fører ikke bare til problemene ovenfor, men avslører også mer grunnleggende problemer som hindret andre funksjoner i å bli implementert i den eksisterende objektmodellen.

I PHP 5 ble objektmodellen fullstendig omskrevet for umiddelbart å jobbe med objektpekere. Med mindre du eksplisitt kloner et objekt ved å bruke nøkkelordet klone, vil du aldri jobbe med en kopi av et objekt, og tenker at du jobber med selve objektet. I PHP 5 trenger du ikke lenger eksplisitt å sende objekter eller tildele dem ved referanse, dette gjøres.

Merk at eksplisitt bestått og tildeling ved referanse også støttes i tilfelle du ønsker å endre innholdet i en variabel eller et objekt.

Ny objektorientert tilnærming i PHP5

De nye funksjonene i objektmodellen er for mange. Her er en oversikt over de viktigste endringene:

  1. offentlig/privat/beskyttet - tilgangsmodifikatorer for metoder og egenskaper

    Lar deg kontrollere tilgang til metoder og egenskaper. Synligheten til egenskaper og metoder kan nå bestemmes søkeord: offentlig, privat, beskyttet. Modifikator offentlig lar deg få tilgang til egenskaper og metoder fra hvor som helst. Modifikator privat lar deg få tilgang til egenskaper og metoder kun innenfor gjeldende klasse. Modifikator beskyttet lar deg bare få tilgang til egenskaper og metoder for gjeldende klasse og en klasse som arver egenskapene og metodene til gjeldende klasse.

    /**
    * Definer MyClass
    */
    klasse MyClass
    {
    public $public = "Offentlig" ;
    protected $protected = "Beskyttet" ;
    private $private = "Privat" ;

    Funksjon printHello()
    {
    echo $this -> offentlig ;
    echo $this -> beskyttet ;
    echo $this -> privat ;
    }
    }

    $obj = ny MyClass();
    echo $obj -> offentlig ; //Virker
    echo $obj -> beskyttet ; // Fatal feil
    echo $obj -> privat ; // Fatal feil
    $obj -> printHello(); // Viser offentlig, beskyttet og privat

    /**
    * Definer MyClass2
    */
    klasse MyClass2 utvider MyClass
    {
    // Vi kan omerklære den offentlige og beskyttede metoden, men ikke privat
    protected $protected = "Beskyttet2" ;

    Funksjon printHello()
    {
    echo $this -> offentlig ;
    echo $this -> beskyttet ;
    echo $this -> privat ;
    }
    }

    $obj2 = ny MinKlasse2();
    echo $obj -> offentlig ; //Virker
    echo $obj2 -> privat ; // Udefinert
    echo $obj2 -> beskyttet ; // Fatal feil
    $obj2 -> printHello(); // Viser offentlig, beskyttet2, ikke privat

    ?>

  2. Unified constructor __construct()

    PHP 5 lar deg deklarere konstruktørmetoder. Klasser som erklærer en konstruktørmetode vil kalle den metoden hver gang et nytt objekt opprettes, så dette kan være nyttig for for eksempel å initialisere et objekts tilstand før du bruker det. Konstruktøren, tidligere den samme som klassenavnet, må nå deklareres som __konstruksjon(), som vil gjøre det enklere å flytte klasser i hierarkier.Konstruktører i overordnede klasser kalles ikke automatisk. For å kalle en konstruktør deklarert i en overordnet klasse, må du kalle metoden overordnet::__construct().

    klasse BaseClass(
    funksjon __construct() (
    skrive ut "BaseClass-klassekonstruktør\n";
    }
    }

    Class SubClass utvider BaseClass (
    funksjon __construct() (
    overordnet::__construct();
    skrive ut "Konstruktør av klassen underklasse\n";
    }
    }

    $obj = ny BaseClass();
    $obj = ny underklasse();
    ?>

    Hvis PHP 5 ikke kan oppdage en deklarert metode __konstruksjon(), vil konstruktøren kalles i henhold til forrige skjema, gjennom et kall til en metode hvis navn tilsvarer navnet på klassen. Det kan bare være ett kompatibilitetsproblem med gammel kode hvis den inneholder klasser med metoder __konstruksjon().

  3. Destructor-støtte for en klasse definert som __destructor()-metoden

    PHP 5 introduserer et konsept med destruktorer som ligner på de som brukes i andre objektorienterte språk som Java: når frigjort siste lenke på et objekt, før du frigjør minnet som er okkupert av dette objektet, kalles metoden __destruct(), som ikke godtar parametere.

    klasse MyDestructableClass(
    funksjon __construct() (
    skriv ut "Konstruktør\n" ;
    $this -> name = "MyDestructableClass" ;
    }

    Funksjonen __destruct() (
    print "Ødelagt" . $this -> navn . "\n" ;
    }
    }

    $obj = ny MyDestructableClass();
    ?>

    Som med konstruktører, vil ikke destruktorer som er deklarert i en overordnet klasse bli kalt automatisk. For å kalle en destruktor deklarert i en overordnet klasse, bør du bruke metoden forelder::__destruct().

<<< Назад Innhold Videresend >>>
Hvis du har andre spørsmål eller noe er uklart - velkommen til vår