Objektinis PHP: ypač pradedantiesiems. Objektinis PHP: daugiau apie klasės metodus ir laukus 1 ypatybių apibrėžimo pavyzdys

Klasės ir objektai PHP

Klasė yra pagrindinė objektinio programavimo (OOP) koncepcija. Klasės sudaro OOP sintaksinį pagrindą. Jie gali būti laikomi savotiškais logiškai susijusių duomenų ir funkcijų „konteineriais“ (dažniausiai vadinami – žr. toliau). Paprasčiau tariant, klasė yra tam tikras duomenų tipas.

Klasės pavyzdys yra objektas. Objektas – tai duomenų () ir jiems apdoroti skirtų funkcijų (metodų) rinkinys. Savybės ir metodai vadinami. Apskritai objektas yra viskas, kas palaiko inkapsuliavimą.

Jei klasė gali būti laikoma duomenų tipu, tai objektas gali būti laikomas kintamuoju (analogiškai). Scenarijus vienu metu gali dirbti su keliais tos pačios klasės objektais, kaip ir su keliais kintamaisiais.

Objekte duomenys ir kodas (klasės nariai) gali būti vieši arba ne. Vieši duomenys ir klasės nariai yra prieinami kitoms programos dalims, kurios nėra objekto dalis. Tačiau privatūs duomenys ir klasės nariai pasiekiami tik šiame objekte.

PHP klasių aprašymai prasideda funkciniu žodžiu klasė:

klasė klasės pavadinimas (
// klasės narių aprašymas – savybės ir jų apdorojimo metodai
}

Norėdami deklaruoti objektą, turite naudoti operatorių naujas:

Objektas = naujas klasės pavadinimas;

Duomenys aprašomi naudojant funkcinį žodį var. Metodas aprašomas taip pat, kaip įprasta vartotojo apibrėžta funkcija. Taip pat metodui galite perduoti parametrus.

Apibendrinkime: klasės deklaracija turi prasidėti raktiniu žodžiu klasė(panašiai kaip funkcijos deklaracija prasideda raktiniu žodžiu funkcija). Prieš kiekvieną klasėje esančią nuosavybės deklaraciją turi būti nurodytas raktinis žodis var. Savybės gali būti bet kokio tipo duomenys, palaikomi PHP, ir gali būti laikomi kintamaisiais su nedideliais skirtumais. Po ypatybių deklaracijų seka metodų deklaracijos, kurios yra labai panašios į įprastas vartotojo apibrėžtas funkcijų deklaracijas.

Pagal visuotinai priimtas taisykles, OOP klasių pavadinimai prasideda didžiosiomis raidėmis, o visi žodžiai metodų pavadinimuose, išskyrus pirmąjį, prasideda didžiosiomis raidėmis (pirmasis žodis prasideda mažąja raide). Žinoma, galite naudoti bet kokius jums patogius užrašus; svarbiausia pasirinkti standartą ir jo laikytis.

PHP klasės pavyzdys:

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;
var $addr;

// metodai:
funkcijos pavadinimas() (
aidas"

Jonas

" ;
}

}


$objektas = newCoor;
?>

Prieiga prie klasių ir objektų PHP

Pažiūrėjome, kaip aprašomos klasės ir kuriami objektai. Dabar turime pasiekti klasės narius, tam PHP yra operatorius -> . Štai pavyzdys:

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;

// metodai:
funkcija Getname() (
aidas"

Jonas

" ;
}

}

// Sukurkite Coor klasės objektą:
$objektas = newCoor;
// Gaukite prieigą prie klasės narių:
$objektas -> vardas = "Aleksas" ;
echo $objektas -> vardas ;
// Spausdina "Alex"
// Dabar prieikime prie klasės metodo (iš tikrųjų tai klasėje esanti funkcija):
$objektas -> Getname();
// Spausdina "Jonas" didžiosiomis raidėmis
?>

Norėdami pasiekti klasės narius klasėje, turite naudoti žymeklį $tai, kuris visada nurodo esamą objektą. Modifikuotas metodas Gauti vardą ():

funkcija Getname() (
echo $this->name;
}

Taip pat galite parašyti metodą Nustatyti pavadinimas ():

function Setname($name) (
$šis->vardas = $vardas;
}

Dabar galite pakeisti pavadinimą naudodami šį metodą Nustatyti pavadinimas ():

$objektas->Setname("Petras");
$objektas->Gautivardas();

Ir čia yra visas kodų sąrašas:

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;

// metodai:
funkcija Getname() (
echo $this -> vardas ;
}

function Setname($name) (
$šis -> vardas = $vardas ;
}

}

// Sukurkite Coor klasės objektą:
$objektas = newCoor;
// Dabar norėdami pakeisti pavadinimą naudojame Setname() metodą:
$objektas -> Setname("Slapyvardis");
// O prieigai, kaip ir anksčiau, Getname():
$objektas -> Getname();
// Scenarijus išspausdina "Nikas"
?>

Rodyklė $tai taip pat gali būti naudojamas norint pasiekti metodus, o ne tik prieigą prie duomenų:

function Setname($name) (
$šis->vardas = $vardas;
$this->Getname();
}

Konstruktoriai

Gana dažnai kuriant objektą reikia nustatyti kai kurių savybių reikšmes. Laimei, OOP technologijos kūrėjai atsižvelgė į šią aplinkybę ir įgyvendino ją koncepcijoje. Konstruktorius yra metodas, kuris nustato kai kurių savybių reikšmes (ir gali iškviesti kitus metodus). Konstruktoriai iškviečiami automatiškai, kai sukuriami nauji objektai. Kad tai būtų įmanoma, konstruktoriaus metodo pavadinimas turi atitikti klasės, kurioje jis yra, pavadinimą. Konstruktoriaus pavyzdys:

klasės tinklalapis (
var $bgcolor;
funkcija tinklalapis($spalva)(
$this -> bgcolor = $spalva ;
}
}

// Iškvieskite tinklalapio klasės konstruktorių
$puslapis = naujas tinklalapis("rudas");
?>

Anksčiau objektų kūrimas ir nuosavybės inicijavimas buvo atliekami atskirai. Dizaineriai leidžia atlikti šiuos veiksmus vienu žingsniu.

Įdomi detalė: priklausomai nuo perduotų parametrų skaičiaus, galima iškviesti skirtingus konstruktorius. Nagrinėjamame pavyzdyje klasės objektai Tinklo puslapis galima sukurti dviem būdais. Pirma, galite iškviesti konstruktorių, kuris tiesiog sukuria objektą, bet neinicijuoja jo savybių:

$puslapis = naujas tinklalapis;

Antra, objektą galima sukurti naudojant klasėje apibrėžtą konstruktorių – tokiu atveju sukuriate tinklalapio klasės objektą ir priskiriate jo ypatybei reikšmę. bgcolor:

$puslapis = naujas tinklalapis("rudas");

Destruktoriai

PHP tiesioginio palaikymo nėra. Tačiau jūs galite lengvai imituoti naikintoją iškviesdami PHP funkciją unset (). Ši funkcija sunaikina kintamojo turinį ir grąžina sistemai jo užimtus išteklius. Su daiktais unset () veikia taip pat, kaip ir su kintamaisiais. Tarkime, kad dirbate su objektu $Tinklalapis. Baigus darbą su šiuo konkrečiu objektu, funkcija vadinama:

unset($tinklalapis);

Ši komanda ištrina visą turinį iš atminties $Tinklalapis. Inkapsuliacijos dvasia galite paskambinti unset ()į metodą, pavadintą sunaikinti () ir tada vadink:

$Website->destroy();

Destruktorių iškvietimo poreikis atsiranda tik dirbant su objektais, kurie naudoja daug išteklių, nes visi kintamieji ir objektai automatiškai sunaikinami pasibaigus scenarijui.

Objektų inicijavimas

Kartais reikia inicijuoti objektą – priskirti jo savybes pradinėms reikšmėms. Tarkime, kad klasės pavadinimas yra Coor ir jame yra dvi savybės: asmens vardas ir pavardė bei jo gyvenamosios vietos miestas. Pavyzdžiui, galite parašyti metodą (funkciją), kuris inicijuos objektą Init ():

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;
var $city;

// Inicijuojimo metodas:
funkcija Init($name) (
$šis -> vardas = $vardas ;
$ this -> city = "Londonas" ;
}

}

// Sukurkite Coor klasės objektą:
$objektas = newCoor;
// Norėdami inicijuoti objektą, nedelsdami iškvieskite metodą:
$objektas -> Init();
?>

Svarbiausia nepamiršti iškviesti funkcijos iš karto sukūrus objektą arba iškviesti kokį nors metodą tarp kūrimo (operatoriaus naujas) objektas ir jo inicijavimas (skambinimas Init).

Kad PHP žinotų, kad tam tikras metodas turi būti iškviestas automatiškai, kai sukuriamas objektas, jam turi būti suteiktas toks pat pavadinimas kaip ir klasei ( Coor):

funkcija Coord ($name)
$šis->vardas = $vardas;
$this->city = "Londonas";
}

Metodas, kuris inicijuoja objektą, vadinamas konstruktoriumi. Tačiau PHP neturi destruktorių, nes ištekliai išleidžiami automatiškai, kai scenarijai išeina.

Prieiga prie klasės elementų

Klasės elementai pasiekiami naudojant operatorių :: "dvi dvitaškis" Naudodami „dvigubą dvitaškį“ galite pasiekti klasės metodus.

Pasiekdamas klasės metodus, programuotojas turi naudoti šių klasių pavadinimus.

A klasė (
funkcijos pavyzdys() (
aidas "Tai yra originali A::example() funkcija.
"
;
}
}

B klasė išplečia A (
funkcijos pavyzdys() (
aidas "Tai yra B::example() nepaisymas.
"
;
A::example();
}
}

// Nereikia kurti A klasės objekto.
// Išveda šiuos duomenis:
// Tai originali A::example() funkcija.
A::example();

// Sukurkite B klasės objektą.
$b = naujas B PHP portalo forumas. S.U.

Objektai

Objektas yra viena iš pagrindinių objektinio programavimo sąvokų.

Objektas yra kintamasis, kurio egzempliorius sukuriamas naudojant specialų šabloną, vadinamą klasė. Objektų ir klasių sąvokos yra neatsiejama objektinio programavimo (OOP) paradigmos dalis.

Objektas – tai duomenų (savybių) ir funkcijų (metodų) rinkinys jiems apdoroti. Duomenys ir metodai vadinami klasės nariais. Apskritai objektas yra viskas, kas palaiko inkapsuliavimą.

Vidinė objekto struktūra yra panaši į maišą, išskyrus tai, kad operatorius -> naudojamas atskiriems elementams ir funkcijoms pasiekti, o ne laužtiniams skliaustams.

Norėdami inicijuoti objektą, naudokite naują išraišką, kuri sukuria objekto egzempliorių kintamajame.

klasė foo
{
funkcija do_foo()
{
aidas "Daryk kvailą". ;
}
}

$bar = naujas foo ;
$bar -> do_foo();
?>

Objekte duomenys ir kodas (klasės nariai) gali būti vieši arba ne. Vieši duomenys ir klasės nariai yra prieinami kitoms programos dalims, kurios nėra objekto dalis. Tačiau privatūs duomenys ir klasės nariai pasiekiami tik šiame objekte.

PHP klasių aprašymai prasideda funkciniu žodžiu klasė:

klasė klasės pavadinimas (
// klasės narių aprašymas – duomenys ir jų apdorojimo metodai
}

Dėl paskelbimo objektas turi būti naudojamas operatorius naujas:

Objektas = naujas klasės pavadinimas;

Duomenys aprašomi naudojant funkcinį žodį var. Metodas aprašomas taip pat, kaip ir įprasta funkcija. Taip pat metodui galite perduoti parametrus.

PHP klasės pavyzdys:

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;
var $addr;

// metodai:
funkcijos pavadinimas() (
aidas"

Jonas

" ;
}

}

// Sukurti objektas Coor klasė:
$objektas = newCoor;
?>

Prieiga prie klasių ir objektų PHP

Pažiūrėjome, kaip aprašomos klasės ir kuriami objektai. Dabar turime pasiekti klasės narius, tam PHP yra operatorius -> . Štai pavyzdys:

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;

// metodai:
funkcija Getname() (
aidas"

Jonas

" ;
}

}


$objektas = newCoor;
// Gaukite prieigą prie klasės narių:
$objektas -> vardas = "Aleksas" ;
echo $objektas -> vardas ;
// Spausdina "Alex"
// Dabar prieikime prie klasės metodo (iš tikrųjų tai klasėje esanti funkcija):
$objektas -> Getname();
// Spausdina "Jonas" didžiosiomis raidėmis
?>

Norėdami pasiekti klasės narius klasėje, turite naudoti žymeklį $tai, kuris visada nurodo esamą objektą. Modifikuotas metodas Gauti vardą ():

funkcija Getname() (
echo $this->name;
}

Taip pat galite parašyti metodą Nustatyti pavadinimas ():

function Setname($name) (
$šis->vardas = $vardas;
}

Dabar galite pakeisti pavadinimą naudodami šį metodą Nustatyti pavadinimas ():

$objektas->Setname("Petras");
$objektas->Gautivardas();

Ir čia yra visas kodų sąrašas:

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;

// metodai:
funkcija Getname() (
echo $this -> vardas ;
}

function Setname($name) (
$šis -> vardas = $vardas ;
}

}

// Sukurkite Coor klasės objektą:
$objektas = newCoor;
// Dabar norėdami pakeisti pavadinimą naudojame Setname() metodą:
$objektas -> Setname("Slapyvardis");
// O prieigai, kaip ir anksčiau, Getname():
$objektas -> Getname();
// Scenarijus išspausdina "Nikas"
?>

Rodyklė $tai taip pat gali būti naudojamas norint pasiekti metodus, o ne tik prieigą prie duomenų:

function Setname($name) (
$šis->vardas = $vardas;
$this->Getname();
}

Objektų inicijavimas

Kartais reikia inicijuoti objektą – priskirti jo savybes pradinėms reikšmėms. Tarkime, klasės pavadinimas yra Coor ir joje yra dvi savybės: asmens vardas ir jo gyvenamasis miestas. Pavyzdžiui, galite parašyti metodą (funkciją), kuris inicijuos objektą Init ():

// Sukurti naują Coor klasę:
klasė Coor (
// duomenys (ypatybės):
var$vardas;
var $city;

// Inicijuojimo metodas:
funkcija Init($name) (
$šis -> vardas = $vardas ;
$ this -> city = "Londonas" ;
}

}

// Sukurkite Coor klasės objektą:
$objektas = newCoor;
// Norėdami inicijuoti objektą, nedelsdami iškvieskite metodą:
$objektas -> Init();
?>

Svarbiausia nepamiršti iškviesti funkcijos iš karto sukūrus objektą arba iškviesti kokį nors metodą tarp kūrimo (operatoriaus naujas) objektas ir jo inicijavimas (skambinimas Init).

Kad PHP žinotų, kad tam tikras metodas turi būti iškviestas automatiškai, kai sukuriamas objektas, jam turi būti suteiktas toks pat pavadinimas kaip ir klasei ( Coor):

funkcija Coord ($name)
$šis->vardas = $vardas;
$this->city = "Londonas";
}

Metodas, kuris inicijuoja objektą, vadinamas konstruktoriumi. Tačiau PHP neturi destruktorių, nes ištekliai išleidžiami automatiškai, kai scenarijai išeina.

Konvertuoti į objektą

Jei objektas konvertuojamas į objektą, jis nekeičiamas. Jei bet kurio kito tipo reikšmė konvertuojama į objektą, sukuriamas naujas integruotos klasės stdClass egzempliorius. Jei reikšmė buvo tuščia, naujas egzempliorius taip pat bus tuščias. Bet kuriai kitai vertei ji bus įtraukta į skaliarinio nario kintamąjį:

PHP portalo forumas. S.U.

Šioje pamokoje išmoksite objektinio programavimo PHP kalboje pagrindus. Sužinosite apie OOP principus apskritai ir išmoksite rašyti paprastus scenarijus PHP kalba.

Sveiki atvykę į pirmąsias pamokas apie OOP PHP kalba! Baigę visas šios serijos pamokas, sužinosite apie pagrindinius OOP principus ir sąvokas bei sužinosite, kaip greitai ir lengvai kurti naudingas programas PHP.

Šiame vadove papasakosiu apie pagrindines OOP sąvokas. Tu išmoksi:

  • kas yra OOP
  • kaip OOP padės sukurti geresnius PHP scenarijus
  • kai kurios pagrindinės sąvokos, tokios kaip klasės, objektai, metodai, klasių kintamieji
  • kur pradėti rašyti PHP scenarijų

Ar esate pasirengęs pasinerti į PHP objektų pasaulį? Tada pirmyn!

Kas yra objektinis programavimas?

Jei kada nors sukūrėte ir naudojote pasirinktines PHP funkcijas, naudojote procedūrinį programavimo stilių. Procedūrinio programavimo metu paprastai kuriate duomenų struktūras – skaičius, eilutes, masyvus ir kt. - saugoti kai kuriuos duomenis ir apdoroti šias struktūras specialiomis funkcijomis, kurios manipuliuoja šiais duomenimis.

Objektinis programavimas arba OOP pažengė į priekį, nes čia duomenų struktūras ir jas apdorojančias funkcijas saugome viename objekte, vadinamame objektu. Užuot apdoroję duomenis naudodami kokią nors funkciją, įkeliate tuos duomenis į objektą ir iškviečiate jo metodus, kad galėtumėte jais manipuliuoti ir gauti norimą rezultatą.

Dažniausiai objektai, sukurti naudojant OOP, atspindi tikrus objektus. Pavyzdžiui, jei kuriate savo svetainės forumą, sukursite nario objektą, kuriame bus saugoma informacija apie kiekvieną forumo narį (vardas, prisijungimo vardas, el. paštas, slaptažodis ir kt.), taip pat metodai, kurie apdoros šią informaciją ( registracija, autorizacija, atsijungimas, draudimas ir pan.).

Kodėl naudoti OOP?

Procedūrinis ir į objektą orientuotas yra du skirtingi būdai daryti tą patį. Tai nereiškia, kad vienas iš jų geresnis už kitą – kiekvienas rašo taip, kaip jam patinka, todėl šiuos du požiūrius galite netgi lengvai sujungti viename scenarijuje.

Tačiau čia yra keletas OOP pranašumų kūrėjams:

  • Lengviau atspindėti realias situacijas: kaip jau minėjau aukščiau, objektai atspindi realias esybes – žmones, produktus, korteles, tinklaraščio straipsnius ir pan. Tai labai supaprastina užduotį, kai tik pradedate kurti savo programą, nes kiekvieno objekto paskirtis yra tarsi tikslas, santykiai tarp objektų bus aiškūs ir suprantami.
  • Modulines programas rašyti lengviau: OOP apima modulių rašymą. Padalijus kodą į modulius, jums bus lengviau jį valdyti, derinti ir išplėsti.
  • Paprasčiau rašyti kodą, kuris bus naudojamas daug kartų: Rašydami kodą, kurį galima naudoti daugiau nei vieną kartą, sutaupysite laiko rašydami programą, o laikui bėgant netgi galėsite sukurti visą tokių modulių biblioteką, kurią galėsite naudoti daugelyje programos. Naudojant OOP, tokį kodą rašyti tampa palyginti lengviau, nes duomenų struktūros ir funkcijos yra įdėtos į vieną objektą, kurį galima naudoti bet kokį skaičių kartų.

Kai kurios pagrindinės sąvokos

Prieš pradėdami rašyti scenarijus, turite gerai suprasti klasės, objekto, klasės kintamojo ir metodo sąvokas.

Klasės

Klasė yra objekto struktūra. Tai yra kodo dalis, kuri apibrėžia:

  • Duomenų tipai, kuriuos turės sukurti klasės objektai
  • Funkcijos, kuriose bus šie objektai.

Kai kuriate OOP programą, paprastai sukursite keletą klasių, kurios atstovaus skirtingus jūsų programos objektų tipus. Pavyzdžiui, norėdami sukurti forumą, galite sukurti forumo, temos, įrašo ir narių klases.

Objektai

Objektas yra specialaus tipo kintamasis, kuris sukuriamas per klasę. Jame yra tikri duomenys ir funkcijos, skirtos jais valdyti. Iš vienos klasės galite sukurti tiek objektų, kiek norite. Kiekviena objekto funkcija nepriklauso nuo kito objekto, net jei jie sukurti iš tos pačios klasės.

Palyginimui su tikrais subjektais:

  • Klasė yra automobilio pagrindas: ji apibrėžia, kaip automobilis atrodys ir veiks, bet vis tiek yra abstraktus subjektas.
  • Objektas yra tikras automobilis, sukurtas iš vielinio rėmo: jis turi realias savybes (tokias kaip greitis) ir elgseną (pavyzdžiui, greitėjimą ar stabdymą).

Pastaba: objektas dažnai vadinamas klasės esme, o klasės objekto kūrimo procesas vadinamas įgyvendinimu.

Klasės kintamieji

Duomenų reikšmės, saugomos konkrečiame objekte, įrašomos į specialius kintamuosius, vadinamus klasės kintamaisiais. Klasės kintamieji yra glaudžiai susiję su jos objektu. Nors visi klasės objektai turi tuos pačius kintamuosius, jų reikšmės gali skirtis.

Metodai

Funkcijos, apibrėžtos klasėje ir naudojamos tos klasės objektams, vadinamos metodais. Jos nedaug skiriasi nuo įprastų funkcijų – galite joms perduoti reikšmes, jose gali būti vietinių kintamųjų ir grąžinamos reikšmės. Tačiau metodai dažniau veikia su objekto kintamaisiais. Pavyzdžiui, prisijungimo() metodas, skirtas naudotojams prisijungti prie jūsų forumo, gali nustatyti loggedIn klasės kintamąjį kaip true.

Kaip sukurti klasę PHP?

Dabar, kai jau žinote, kas yra klasės, metodai, klasių kintamieji ir objektai, laikas sukurti keletą klasių ir objektų PHP kode.

Pirmiausia pažiūrėkime, kaip iš tikrųjų sukurti klasę. Iš esmės klasės kūrimo scenarijus atrodo taip:

Klasės klasės pavadinimas ( // (klasės apibrėžimas) )

Pavyzdžiui, jei kuriate savo forumo narių klasę, parašykite taip:

Klasės narys ( // (klasės apibrėžimas) )

Tai gana paprasta. Natūralu, kad ši klasė nieko nedarys, kol prie jos nepridėsite kintamųjų ir metodų. Tačiau aukščiau pateiktas kodas sukuria galiojančią PHP klasę, kurią galima naudoti.

Gera nykščio taisyklė: įdėkite kiekvieną klasę į atskirą failą tokiu pačiu pavadinimu kaip ir klasės pavadinimas. Pavyzdžiui, Narių klasę įdėkite į Member.php failą ir išsaugokite aplanke, tarkime, klasės.

Kaip sukurti objektus PHP?

Galite sukurti objektą naudodami naują raktinį žodį:

Naujas klasės pavadinimas ()

Šis kodas sukurs klasės ClassName objektą. Šį objektą turėsite naudoti vėliau, todėl turėsite jį išsaugoti kintamajame. Pavyzdžiui, sukurkime Narių klasės objektą ir išsaugokime jį kintamajame $member:

$narys = naujas narys();

Taip pat galime sukurti kitą tos pačios klasės objektą:

$narys2 = naujas narys();

Nors šiuos du objektus sukūrėme iš tos pačios klasės, kintamieji $member ir $member2 nepriklauso vienas nuo kito.

Sukurkite klasės kintamuosius

Dabar, kai jau žinome, kaip kurti klases ir klasių objektus, pažiūrėkime, kaip sukurti klasės kintamuosius. Yra 3 klasės kintamųjų priedai, kuriuos galima pridėti prie klasės:

  • Viešosios klasės kintamieji (viešieji): prieinami – t.y. juos galima skaityti ir (arba) keisti - bet kurioje scenarijaus vietoje, nepriklausomai nuo to, kur yra šis kodas - klasėje arba už jos ribų
  • Privatūs klasės kintamieji (privatūs): prieinami tik klasės metodams. Geriausia klasės kintamuosius padaryti privačius, kad atskirtumėte objektus nuo likusio kodo.
  • Apsaugotų klasių kintamieji: galimi jūsų klasės metodams, taip pat paveldėtų klasių metodams (apie paveldėjimą kalbėsime vėliau).

Norėdami sukurti klasės kintamąjį, parašykite raktinį žodį viešas, privatus arba apsaugotas, tada įveskite kintamojo pavadinimą:

Klasės klasės pavadinimas (viešas $propertyName; privatus $propertyName; apsaugotas $propertyName; )

Pridėkime viešą klasės kintamąjį prie savo narių klasės, kad išsaugotume vartotojo vardą:

Klasės narys (viešas $username = ""; )

Atkreipkite dėmesį, kad inicijavome savo klasės kintamąjį, jo reikšmė yra tuščia eilutė „“. Tai reiškia, kad kai sukuriamas naujas vartotojas, pagal nutylėjimą naudotojo vardas bus tuščia eilutė. Kaip ir įprastų PHP kintamųjų atveju, klasės kintamieji neturi būti inicijuojami, tačiau geriau netingėti. Jei nepainicijuosite klasės kintamojo, jo numatytoji reikšmė yra nulinė.

Prieiga prie klasės kintamųjų

Norėdami gauti prieigą prie objekto kintamojo, naudokite operatorių ->:

$object->propertyName

Pabandykime. Parašykime scenarijų, kuris deklaruoja narių klasę ir klasės kintamąjį, sukuria šios klasės objektą, tada nustato klasės kintamojo reikšmę ir parodo ją ekrane:

vartotojo vardas = "Fredas"; echo $nary->naudotojo vardas; // Spausdinti "Fredas" ?>

Paleiskite šį kodą, jis parodys eilutę „Fred“, klasės kintamojo $member->username reikšmę. Kaip matote, objekto kintamąjį veikiate kaip ir įprastą kintamąjį – galite nustatyti jam reikšmę ir jį perskaityti.

Metodų įtraukimas į klasę

O kaip su metodų kūrimu? Kaip jau minėjau anksčiau, metodai yra tik įprastos funkcijos, kurios yra klasės dalis. Taigi galite nenustebti, kad jie sukurti naudojant tą patį raktinį žodį. Vienintelis skirtumas nuo įprastų funkcijų kūrimo yra tas, kad prie jo deklaracijos taip pat galite pridėti vieną iš prieigos identifikatorių (viešą, privatų, apsaugotą). Tokiu būdu metodai yra panašūs į klasės kintamuosius:

Klasės pavadinimas (viešosios funkcijos metodasPavadinimas() ( // (kodas) ) privačios funkcijos metodasPavadinimas() ( // (kodas) ) apsaugotos funkcijos metodasPavadinimas() ( // (kodas) ) )

Pastaba: kaip ir klasės kintamųjų atveju, viešuosius metodus galima iškviesti iš bet kur, privačius metodus galima iškviesti tik klasėje, o apsaugotus metodus galima iškviesti iš pačios klasės ir jos palikuonių.

Pabandykime į savo klasę įtraukti keletą metodų ir klasės kintamųjų:

  • privatus $loggedIn klasės kintamasis vartotojui identifikuoti, t.y. ar jis atėjo, ar ne,
  • login() metodas, kuris prisijungs prie forumo, nustatydamas $loggedIn klasės kintamąjį į true,
  • logout() metodas, kuris atsijungs nuo forumo, nustatydamas $loggedIn klasės kintamąjį į false,
  • isLoggedIn() metodas, kuris grąžins $loggedIn klasės kintamojo reikšmę.

Štai mūsų kodas:

prisijungęs = tiesa; ) public function logout() ( $this->loggedIn = false; ) public function isLoggedIn() ( return $this->loggedIn; ) ) ?>

Galbūt pastebėjote, kad naudojome naują $this raktinį žodį. Objekto metodų kontekste specialusis kintamasis $this nurodo patį objektą. Objekto metodu naudojant $this, metodas gali pasiekti bet kurį objekto klasės kintamąjį ir metodą.

Pavyzdžiui, metodas login() gali pasiekti objekto $loggedIn klasės kintamąjį per $this->loggedIn.

Beje, mūsų klasės kintamasis yra privatus, todėl jo negalima iškviesti iš jokios scenarijaus dalies, o tik iš login(), logout() ir isLoggedIn() metodų. Tai geras būdas, nes objekto vidinės dalys (pvz., kaip tiksliai įrašo, ar vartotojas yra prisijungęs, ar ne) yra atskirtos nuo likusios kodo dalies. Kai tik įmanoma, stenkitės naudoti privačių klasių kintamuosius, kad jūsų objektai būtų autonomiški, mobilūs ir apsaugoti.

Pastaba: mūsų pavyzdyje $username klasės kintamasis yra viešas. Tai padariau tik norėdamas parodyti, kaip galite pasiekti objekto klasės kintamuosius. Realiuose projektuose verčiau šį kintamąjį paverskite privačiu ir sukurkite specialius viešosios klasės kintamuosius, kad prireikus nustatytumėte vartotojo vardo reikšmes.

Metodų naudojimas

Norėdami iškviesti objekto metodą, naudokite operatorių ->, su kuriuo jau susipažinote.

$object->methodName()

Tai veikia taip pat, kaip įprastos funkcijos iškvietimas. Argumentus galite perduoti skliausteliuose (žinoma, jei reikia bet kokių argumentų), o metodo iškvietimas taip pat gali grąžinti konkrečias reikšmes, kurias galite naudoti.

prisijungęs = tiesa; ) public function logout() ( $this->loggedIn = false; ) public function isLoggedIn() ( return $this->loggedIn; ) ) $nember = new Member(); $member->username = "Fredas"; echo $nember->naudotojo vardas . "yra". ($ narys->
"; $member->login(); echo $member->username . " yra " . ($member->isLoggedIn() ? "prisijungęs" : "atsijungęs") . "
"; $member->logout(); echo $member->username . " yra " . ($member->isLoggedIn() ? "prisijungęs" : "atsijungęs") . "
"; ?>

Šis scenarijus parodys:

Fredas yra atsijungęs Fredas prisijungęs Fredas yra atsijungęs

Štai kaip tai veikia:

  1. Aprašę narių klasę, sukūrėme jos objektą ir įrašėme jį į $member kintamąjį. Šio objekto klasės kintamajam $username taip pat suteikėme reikšmę „Fred“.
  2. Tada iškvietėme $member->isLoggedIn() metodą, kad nustatytų, ar vartotojas yra prisijungęs, ar ne. Šis metodas tiesiog grąžina $loggedIn klasės kintamojo reikšmę. Kadangi numatytoji šio klasės kintamojo reikšmė yra false, $member->isLoggedIn() iškvietimo rezultatas bus klaidingas, todėl bus rodomas pranešimas "Fred is logged out".
  3. Tada mes iškviečiame prisijungimo () metodą. Tai nustatys $loggedIn klasės kintamąjį į true.
  4. Dabar, kai iškviečiamas $member->isLoggedIn() metodas, jis grąžins true ir parodys pranešimą "Fred yra prisijungęs".
  5. Iškvieskime logout() metodą, kuris nustato $loggedIn ypatybės reikšmę false.
  6. Iškvieskime $member->isLoggedIn() metodą trečią kartą. Dabar jis grįš false, nes $loggedIn ypatybė vėl nustatyta į false. Taigi vėl bus rodomas pranešimas „Fredas atsijungęs“.

Pastaba: jei tai pamatėte pirmą kartą: ?: yra trijų dalių operatorius. Tai supaprastinta if...else blokų versija. Galite sužinoti apie šių tipų operatorius.

išvadas

Šioje pamokoje sužinojote OOP pagrindus PHP. Sužinojote apie tokius dalykus kaip:

  • Kas yra OOP ir kodėl tai naudinga?
  • klasių, objektų, klasių kintamųjų ir metodų sąvokos
  • kaip sukurti klases ir objektus
  • kaip sukurti ir naudoti klasės kintamuosius
  • viešųjų, privačių, apsaugotų prieigos identifikatorių sąvokos
  • kaip sukurti ir naudoti klasės metodus

Jau daug apie tai sužinojote ir daug daugiau sužinosite per kitas pamokas. Tačiau jei išnagrinėjote visus mano pateiktus pavyzdžius, turite tvirtą pagrindą. Galite pradėti kurti programas naudodami OOP.

Sveiki atvykę į antrąją OOP serijos pamoką. Pirmajame straipsnyje sužinojote PHP OOP pagrindus, įskaitant klasių, metodų, laukų ir objektų sąvokas. Taip pat išmokote sukurti paprastą klasę ir ją įgyvendinti.

Šiame straipsnyje dar daugiau sužinosite apie klasės metodus ir laukus. Tai suteiks jums gerą pagrindą pradėti mokytis pažangesnių metodų, tokių kaip paveldėjimas.

Štai sąrašas to, apie ką papasakosiu šiame straipsnyje:

  • Konstruktoriai ir naikintuvai, leidžiantys priskirti konkrečius veiksmus objektui jį sukuriant ir ištrinant;
  • Statiniai laukai ir metodai yra tie laukai ir metodai, kurie nėra susieti su konkrečiais klasės objektais;
  • Klasės konstantos, naudingos fiksuotoms su konkrečia klase susijusioms reikšmėms saugoti;
  • Aiškus tipo nurodymas, naudojamas nustatyti parametrų tipų apribojimus, kurie gali būti perduodami konkrečiam metodui;
  • Specialūs metodai __get() ir __set(), kurie naudojami klasių laukų reikšmėms nustatyti ir nuskaityti;
  • Specialus metodas __call(), naudojamas klasės metodui iškviesti.

Tu esi pasiruošęs? Tada pirmyn!

Konstruktoriai ir griovėjai

Kartais kai kuriuos veiksmus reikia atlikti kartu su objekto kūrimu. Pavyzdžiui, jums gali tekti nustatyti reikšmes objekto laukams iš karto jį sukūrus arba inicijuoti juos vertėmis iš duomenų bazės.

Panašiai, jums taip pat gali tekti atlikti tam tikrus veiksmus, kad pašalintumėte objektą iš atminties, pvz., ištrinti objektus, kurie priklauso nuo ištrinamo objekto, uždaryti duomenų bazės ryšį arba uždaryti failus.

Pastaba: kaip ištrinti objektą? PHP automatiškai pašalina objektą iš atminties, kai neliko į jį nukreipiančių kintamųjų. Pavyzdžiui, jei sukursite naują objektą ir išsaugosite jį kintamajame $myObject, o tada ištrinsite naudodami unset($myObject) metodą, pats objektas taip pat bus ištrintas. Be to, jei funkcijoje sukūrėte vietinį kintamąjį, jis (kartu su objektu) bus ištrintas, kai funkcija išeina.

PHP turi du specialius metodus, kuriuos galima naudoti norint atlikti konkrečius veiksmus, siekiant sukurti ir ištrinti objektus:

  • Konstruktorius iškviečiamas iš karto po to, kai sukūrei objektą;
  • Destruktorius iškviečiamas griežtai prieš pašalinant objektą iš atminties.

Darbas su konstruktoriais

Naudokite konstruktorius, kad nurodytumėte veiksmus, kurie bus atliekami kuriant klasės objektą. Šie veiksmai gali apimti klasės laukų inicijavimą, failų atidarymą, duomenų skaitymą.

Norėdami sukurti konstruktorių, prie klasės pridėkite specialų metodą __construct() (du pabraukimai prieš žodį construct). PHP automatiškai iškvies šį metodą, kai įdiegiate savo klasę, ty kai kuriate tos klasės objektą.

Štai konstruktoriaus pavyzdys:

Klasė MyClass (viešoji funkcija __construct() ( aidas "Aš ką tik sukurtas!"; ) ) $myObject = new MyClass(); // parodys "Aš ką tik sukurtas!"

MyClass klasėje yra konstruktorius, kuris puslapyje atspausdina eilutę „Aš ką tik sukūriau!“. Paskutinė kodo eilutė sukuria naują MyClass klasės objektą. Kai taip nutinka, PHP automatiškai iškviečia konstruktorių ir pranešimas rodomas naršyklėje. Dabar praktiškai – inicijavimo klasės laukai:

Klasės narys (privatus $naudotojo vardas; privati ​​$vieta; privati ​​$pagrindinis puslapis; viešoji funkcija __construct($naudotojo vardas, $vieta, $pagrindinis puslapis) ( $this->username = $naudotojo vardas; $this->location = $vieta; $this- >homepage = $homepage; ) viešoji funkcija showProfile() ( echo "

"; aidas"
Vartotojo vardas:
$this->naudotojo vardas
"; aidas"
Vieta:
$this->vieta
"; aidas"
Pagrindinis puslapis:
$this->pagrindinis puslapis
"; aidas"
"; ) ) $aNarys = naujas narys("fred", "Čikaga", "http://example.com/"); $aNarys->showProfile();

Šis scenarijus puslapyje parodys:

Vartotojo vardas: fred Vieta: Čikagos pagrindinis puslapis: http://example.com/

Mūsų narių klasėje yra trys laukai ir konstruktorius, kuris kaip parametrus priima 3 reikšmes – po vieną kiekvienam laukui. Konstruktorius priskirs reikšmes, gautas kaip argumentus, objekto laukams. Klasė taip pat turi metodą objekto laukų reikšmėms puslapyje rodyti.

Tada kodas sukuria Narių klasės objektą, kuriam perduodame 3 reikšmes „fred“, „Chicago“ ir „http://example.com/“, nes konstruktorius paima tiksliai 3 parametrus. Konstruktorius įrašo šias reikšmes į sukurto objekto laukus. Galiausiai sukurtame objekte iškviečiamas showProfile() metodas, kad būtų rodomos gautos reikšmės.

Darbas su destruktoriais

Kai objektas pašalinamas iš atminties, naudokite naikintuvą. Gali tekti išsaugoti objektą duomenų bazėje, uždaryti atidarytus failus, kurie sąveikavo su objektu. Norėdami sukurti naikintuvą, pridėkite __destruct() metodą prie klasės. Jis bus iškviestas prieš pat automatiškai ištrinant objektą. Štai paprastas pavyzdys:

Class MyClass (viešoji funkcija __destruct() ( aidas "Aš tuoj dingsiu - iki pasimatymo!"; // (išvalyti atmintį) ) ) $myObject = new MyClass(); unset($myObject); // rodo "I "Aš tuoj dingsiu - iki gero!"

Sukūrėme paprastą naikintuvą, kuris puslapyje rodo pranešimą. Tada sukūrėme savo klasės objektą ir nedelsdami jį ištrynėme, iškviesdami į objektą nurodančio kintamojo metodą unset(). Prieš pat ištrinant objektą buvo iškviestas naikintojas, kuris naršyklėje parodė pranešimą „I’m about to loss – bye bye!“.

Pastaba: skirtingai nei konstruktoriai, jūs negalite perduoti jokių parametrų destruktoriams.

Destruktorius taip pat iškviečiamas, kai scenarijus išeina, nes visi objektai ir kintamieji ištrinami, kai metodas išeina. Taigi, šis kodas taip pat iškvies naikintuvą:

Class MyClass ( viešoji funkcija __destruct() ( aidas "Aš tuoj dingsiu - iki gero!"; // (išvalyti atmintį) ) ) $myObject = new MyClass(); išeiti; // rodoma "Aš tuoj dingti - iki pasimatymo!"

Be to, jei scenarijus nustoja veikti dėl klaidos, taip pat bus iškviestas destruktorius.

Pastaba: kuriant palikuonių klasės objektus, pirminės klasės konstruktoriai automatiškai neiškviečiami. Pašaukiamas tik pats įpėdinio konstruktorius. Tačiau galite iškviesti pirminį konstruktorių iš poklasio, pavyzdžiui:

tėvas::__konstrukti(). Tas pats pasakytina apie destruktorius. Pirminio naikintoją galite iškviesti taip: parent:__destruct(). Kitoje paveldėjimo pamokoje papasakosiu apie tėvų ir vaikų klases.

Statiniai klasės laukai

Statinius kintamuosius apžvelgėme straipsnyje PHP kintamųjų apimtis: viskas, ką reikia žinoti. Kaip ir įprastas vietinis kintamasis, statinis kintamasis pasiekiamas tik funkcijoje. Tačiau, skirtingai nei įprasti vietiniai kintamieji, statiniai kintamieji išlaiko savo reikšmes tarp funkcijų iškvietimų.

Statiniai klasės laukai veikia tuo pačiu principu. Statinis klasės laukas yra susietas su jo klase, tačiau jis išlaiko savo vertę visame scenarijuje. Palyginkite tai su įprastais laukais: jie yra susieti su konkrečiu objektu ir prarandami tą objektą ištrynus.

Statiniai laukai naudingi tais atvejais, kai reikia išsaugoti konkrečią reikšmę, kuri taikoma visai klasei, o ne atskiram objektui. Jie yra panašūs į pasaulinių klasių kintamuosius.

Norėdami sukurti statinį kintamąjį, prie jo apibrėžimo pridėkite statinį raktinį žodį:

Klasė MyClass (vieša statinė $myProperty; )

Štai pavyzdys, kaip veikia statiniai kintamieji:

Klasės narys ( privatus $naudotojo vardas; viešas statinis $numMembers = 0; viešoji funkcija __construct($username) ( $this->username = $naudotojo vardas; self::$numMembers++; ) ) echo Member::$numMembers . “
"; // parodys "0" $aMember = new Member("fred"); echo Member::$numMembers . "
"; // parodys "1" $anotherMember = new Member("mary"); echo Member::$numMembers . "
"; // rodo "2"

Yra keletas įdomių dalykų, todėl pažvelkime į šį scenarijų:

  • Narių klasėje yra du laukai: privatus laukas $username ir statinis laukas $numMembers, kuris iš pradžių yra 0;
  • Konstruktorius paima $username argumentą kaip parametrą ir nustato naujai sukurto objekto lauką į šio parametro reikšmę. Tuo pačiu metu jis padidina $numMembers lauko reikšmę, taip aiškiai parodydamas, kad mūsų klasės objektų skaičius padidėjo 1.

Atminkite, kad konstruktorius pasiekia statinį lauką taip: self::$numMembers. Savarankiškas raktinis žodis yra panašus į $this, kurį žiūrėjome paskutinėje pamokoje. Nors $this nurodo esamą objektą, self nurodo dabartinę klasę. Taip pat jei naudojate -> norėdami pasiekti objekto laukus ir metodus, šiuo atveju naudokite :: norėdami pasiekti klasės laukus ir metodus.

  • Galiausiai scenarijus sukuria kelis Member klasės objektus ir puslapyje parodo jų numerį, t.y. statinio kintamojo $numMembers reikšmė. Atminkite, kad šis kintamasis išlaiko savo vertę visame scenarijuje, nepaisant klasės objektų.

Taigi, norėdami pasiekti statinį klasės lauką, naudokite operatorių ::. Čia negalime naudoti savęs raktinio žodžio, nes kodas yra už klasės ribų, todėl rašome klasės pavadinimą, tada :: ir lauko pavadinimą (Member::$numMembers). Konstruktoriui taip pat reikia naudoti tik tokią struktūrą, o ne save.

Pastaba: mūsų scenarijui buvo lengva pasiekti $numMembers klasės lauką prieš sukuriant pirmąjį šios klasės objektą. Norint naudoti jos statinius laukus, nereikia kurti klasės objektų.

Statiniai metodai

Kartu su statiniais klasės laukais taip pat galite kurti statinius metodus. Statiniai metodai, kaip ir laukai, yra susieti su klase, tačiau nereikia kurti klasės objekto, kad būtų galima iškviesti statinį metodą. Dėl to tokie metodai yra naudingi, jei jums reikia klasės, kuri neveikia su realiais objektais.

Norėdami sukurti statinį metodą, prie jo deklaracijos turite pridėti statinį raktinį žodį:

Klasė MyClass (vieša statinė funkcija myMethod() ( // (veiksmai) ) )

Mūsų ankstesnis pavyzdys, susijęs su statiniais laukais, buvo statinis laukas $numMembers. Gera praktika yra padaryti laukus privačius ir būdus, kaip juos pasiekti. Padarykite savo statinį lauką privatų ir parašykite viešą statinį metodą, kad gautume nurodyto lauko vertę:

Klasės narys ( privati ​​$naudotojo vardas; privati ​​statinė $numMembers = 0; viešoji funkcija __construct($username) ( $this->username = $username; self::$numMembers++; ) vieša statinė funkcija getNumMembers() ( grąžinti save::$ numMembers; ) ) echo Member::getNumMembers() . “
"; // parodys "0" $aMember = new Member("fred"); echo Member::getNumMembers() . "
"; // parodys "1" $anotherMember = new Member("mary"); echo Member::getNumMembers() . "
"; // rodo "2"

Čia sukūrėme statinį metodą getNumMembers(), kuris grąžina statinio lauko $numMembers reikšmę. Taip pat šį lauką padarėme privatų, kad jo vertės nebūtų galima gauti iš išorės.

Taip pat pakeitėme iškvietimo kodą, kad naudotume getNumMembers() metodą, kad gautume $numMembers lauko reikšmę. Atkreipkite dėmesį, kad šį metodą galite iškviesti nesukūrę klasės objekto, nes metodas yra statinis.

Klasės konstantos

Konstantos leidžia nustatyti visuotinę viso kodo reikšmę. Ši vertė yra fiksuota ir negali būti pakeista. Klasės konstantos yra panašios į įprastas konstantas. Pagrindinis skirtumas yra tas, kad be to, kad klasės konstanta yra visuotinė, ją galima pasiekti iš klasės, kurioje ji apibrėžta. Klasės konstantos yra naudingos tais atvejais, kai reikia saugoti konkrečias reikšmes, priklausančias konkrečiai klasei.

Klasės konstantą galite apibrėžti naudodami raktinį žodį const. Pavyzdžiui:

Klasė MyClass (konst. CONSTANT_NAME = vertė; )

Vėliau galite pasiekti klasės konstantą naudodami klasės pavadinimą ir operatorių ::. Pavyzdžiui, taip:

MyClass::CONSTANT_NAME

Pastaba: kaip ir naudojant statinius laukus ir metodus, konstantą galite pasiekti naudodami raktinį žodį self.

Pažvelkime į klasės konstantas su pavyzdžiu. Prie narių klasės pridėkime konstantas, kuriose bus saugomos jų vaidmens (dalyvio, moderatoriaus ar administratoriaus) reikšmės. Vietoj įprastų skaitinių reikšmių naudodami konstantas, kodą padarėme skaitomesnį. Štai scenarijus:

Klasės narys ( const MEMBER = 1; const MODERATOR = 2; const ADMINISTRATOR = 3; privatus $ vartotojo vardas; privatus $ lygis; viešoji funkcija __construct($username, $level) ( $this->username = $naudotojo vardas; $this-> level = $level; ) viešoji funkcija getUsername() ( grąžina $this->username; ) viešoji funkcija getLevel() ( if ($this->level == self::MEMBER) grąžina "narį"; if ($this ->level == self::MODERATOR) grąžina "moderatorių"; if ($this->level == self::ADMINISTRATOR) grąžina "administratorių"; grąžina "nežinomas"; ) ) $aMember = new Member(" fred", narys::NARYS); $kitasMember = new Member("mary", Narys::ADMINISTRATORIUS); echo $aMember->getUsername() . "yra". $aMember->getLevel() . “
"; // parodys "fred yra narys" echo $anotherMember->getUsername() . " yra " . $anotherMember->getLevel() . "
"; // rodo "Marija yra administratorė"

Sukūrėme tris klasės konstantas: NARYS, MODERATORIUS ir ADMINISTRATORIUS ir suteikėme joms atitinkamai reikšmes 1, 2 ir 3. Tada pridedame $ lygio lauką vaidmenims saugoti ir šiek tiek modifikuojame konstruktorių, kad inicijuotų šį lauką. Klasė taip pat pridėjo dar vieną metodą – getLevel(), kuris grąžina konkretų pranešimą, priklausomai nuo $level lauko reikšmės. Jis lygina šią reikšmę su kiekviena klasės konstanta ir grąžina norimą eilutę.

Scenarijus sukuria kelis objektus su skirtingais vaidmenimis. Norint priskirti objektams vaidmenis, naudojamos klasių konstantos, o ne paprastos skaitinės reikšmės. Tada kiekviename objekte iškviečiami getUsername() ir getLevel() metodai, o rezultatai rodomi puslapyje.

Aiškiai nurodant funkcijų argumentų tipus

PHP jums nereikia nurodyti duomenų tipų, todėl jums nereikia rūpintis, kokius argumentus perduodate metodams. Pavyzdžiui, galite saugiai perduoti skaitinę reikšmę funkcijai strlen(), kuri apskaičiuoja eilutės ilgį. PHP pirmiausia konvertuos skaičių į eilutę ir grąžins jo ilgį:

Echo strlen(123); // rodyti "3"

Kartais yra naudinga aiškiai nurodyti tipą, tačiau tai gali sukelti klaidų, kurias sunku pašalinti, ypač jei dirbate su sudėtingais duomenų tipais, pvz., objektais.

Pavyzdžiui

Pažvelkite į šį kodą:

Klasės narys ( privatus $naudotojo vardas; viešoji funkcija __construct($username) ( $this->username = $username; ) public function getUsername() ( grąžinti $this->username; ) ) class Topic (privatus $narys; privatus $subject ; viešoji funkcija __construct($narys, $subject) ( $this->member = $narys; $this->subject = $subject; ) viešoji funkcija getUsername() (grąžina $this->member->getUsername(); ) ) $aMember = naujas narys("fred"); $aTopic = nauja tema($aNarys, "Sveiki visi!"); echo $aTopic->getUsername(); // parodys "fred"

Šis scenarijus veikia taip:

  • Kuriame savo klasę Narys naudodami lauką $username, konstruktorių ir metodą getUsername();
  • Taip pat sukuriame temų klasę, kad galėtume tvarkyti forumo straipsnius. Jame yra du laukai: $member ir $subject. $member yra narys klasės objektas, tai bus straipsnio autorius. $temos laukas yra straipsnio tema.
  • Temos klasėje taip pat yra konstruktorius, kuris paima elementą Member ir straipsnio temą atspindinčią eilutę. Jis inicijuoja klasės laukus šiomis reikšmėmis. Jis taip pat turi getUsername() metodą, kuris grąžina forumo nario vardą. Tai pasiekiama iškviečiant nario objekto metodą getUsername().
  • Galiausiai sukuriame Narių klasės objektą, kurio lauko reikšmė vartotojo vardas „fred“. Tada sukuriame objektą iš klasės Tema, perduodame jį Fredui ir straipsnio temą „Sveiki visi!“. Galiausiai iškviečiame Topic klasės metodą getUsername() ir puslapyje pateikiame vartotojo vardą („fred“).

Visa tai labai gerai, bet...

Padarykime geriau!

Pabaigoje pridėkime šią kodo dalį:

Klasės valdiklis ( privatus $spalva; viešoji funkcija __construct($spalva) ( $ši->spalva = $spalva; ) viešoji funkcija getColour() ( grąžinti $this->colour; ) ) $aWidget = naujas valdiklis("mėlynas") ; $antherTopic = nauja tema($aWidget, "Oi!"); // parodys "Mirtinga klaida: iškvietimas į neapibrėžtą metodą Valdiklis::getUsername()" echo $anotherTopic->getUsername();

Čia sukuriame valdiklio klasę su $spalvos lauku, konstruktoriumi ir metodu getColour(), kuris grąžina valdiklio spalvą.

Tada sukursime šios klasės objektą, po kurio bus objektas Topic su argumentu $aWidget, kai iš tikrųjų reikia perduoti straipsnio autorių, t.y. Narių klasės objektas.

Dabar pabandykime iškviesti Topic klasės metodą getUsername(). Šis metodas iškviečia valdiklio klasės metodą getUsername(). Ir kadangi tokio metodo šioje klasėje nėra, gauname klaidą:

Lemtinga klaida: iškvietimas į neapibrėžtą metodą Valdiklis::getUsername()

Problema ta, kad ne taip lengva suprasti klaidos priežastį. Kodėl objektas Topic ieško metodo valdiklio klasėje, o ne Nario? Sudėtingoje klasių hierarchijoje bus labai sunku rasti išeitį iš tokios situacijos.

Mes suteikiame užuominą

Geriau būtų apriboti temos konstruktorių, kad jis priimtų argumentus, kad jis galėtų priimti tik narių objektus kaip pirmąjį parametrą, taip išvengiant lemtingų klaidų.

Būtent tai daro aiškios tipo specifikacijos. Norėdami aiškiai nurodyti parametro tipą, metodo deklaracijoje prieš argumento pavadinimą įterpkite klasės pavadinimą:

Funkcija myMethod(ClassName $object) ( // (veiksmai) )

Pakoreguosime temos klasės konstruktorių, kad jis priimtų tik Narį:

Klasės tema ( privati ​​$narys; privati ​​$subject; public function __construct(Narys $narys, $subject) ( $this->member = $narys; $this->subject = $subject; ) viešoji funkcija getUsername() ( return $ this->member->getUsername(); ) )

Dabar pabandykime dar kartą sukurti temos objektą, perduodami jam valdiklį:

$aWidget = naujas valdiklis("mėlynas"); $antherTopic = nauja tema($aWidget, "Oi!");

Šį kartą PHP parodys konkrečią klaidą:

Pagaunama mirtina klaida: 1 argumentas perduotas temai::__construct() turi būti elemento narys, pateiktas valdiklio egzempliorius, iškviestas script.php 55 eilutėje ir apibrėžtas script.php 24 eilutėje

Šią problemą bus daug lengviau išspręsti, nes tiksliai žinome, kokia yra klaidos priežastis – bandėme perduoti parametrą netinkamo tipo konstruktoriui. Klaidos pranešimas netgi rodo tikslias kodo eilutes, kuriose buvo iškviestas klaidą sukėlęs metodas.

Klasės lauko verčių inicijavimas ir skaitymas naudojant __get() ir __set()

Kaip jau žinote, klasėse paprastai yra laukai:

MyClass klasė (vieša $aProperty; vieša $anotherProperty; )

Jei klasės laukai yra vieši, juos galite pasiekti naudodami operatorių ->:

$myObject = nauja MyClass; $myObject->aProperty = "labas";

Tačiau PHP leidžia kurti „virtualius“ laukus, kurių iš tikrųjų nėra klasėje, bet galima pasiekti naudojant operatorių ->. Jie gali būti naudingi šiais atvejais:

  • Kai turite daug laukų ir norite jiems sukurti masyvą, kad nebūtų deklaruojamas kiekvienas laukas atskirai;
  • Kai reikia saugoti lauką už objekto ribų, pavyzdžiui, kitame objekte arba net faile ar duomenų bazėje;
  • Kai reikia apskaičiuoti lauko reikšmes skrendant, o ne kur nors saugoti jų reikšmes.

Norėdami sukurti tokius „virtualius“ laukus, į klasę turite pridėti keletą stebuklingų metodų:

  • __get($propName) iškviečiamas automatiškai, kai bandoma nuskaityti „nematomo“ lauko $propName reikšmę;
  • __set($propName,$propValue) iškviečiamas automatiškai, kai bandoma nustatyti „nematomą“ lauką $propName į $propValue.

„Nematomas“ šiame kontekste reiškia, kad šių laukų negalima tiesiogiai pasiekti šioje kodo dalyje. Pavyzdžiui, jei tokio lauko klasėje iš viso nėra arba jis yra, bet yra privatus, o už klasės ribų nėra prieigos prie tokio lauko.

Pereikime prie praktikos. Pakeiskime savo narių klasę taip, kad be lauko $username būtų ir kitų atsitiktinių laukų, kurie bus saugomi $data masyve:

Klasės narys ( privatus $naudotojo vardas; privatūs $duomenys = masyvas(); viešoji funkcija __get($property) ( if ($property == "naudotojo vardas") ( return $this->username; ) else ( if (masyvo_key_exists($property) , $this->data)) ( return $this->data[$property]; ) else ( return null; ) ) viešoji funkcija __set($property, $value) (if ($property == "naudotojo vardas" ) ( $this->username = $value; ) else ( $this->data[$property] = $value; ) ) ) $aMember = naujas narys(); $aMember->naudotojo vardas = "fred"; $aMember->location = "San Franciskas"; echo $aMember->naudotojo vardas . “
"; // rodo "fred" echo $aMember->location . "
"; // rodoma "San Franciskas"

Štai kaip tai veikia:

  • Narių klasė turi pastovų lauką privatus $username ir privatų masyvą $data atsitiktiniams "virtualiems" laukams saugoti;
  • Metodas __get() paima vieną parametrą $property – lauko, kurio reikšmė turi būti grąžinta, pavadinimą. Jei $property = "naudotojo vardas", metodas grąžins $username lauko reikšmę. Kitu atveju metodas patikrins, ar tokia $savybė yra $data masyvo raktuose. Jei toks raktas bus rastas, jis grąžins šio lauko reikšmę, kitu atveju - null.
  • Metodas __set() turi 2 parametrus: $property – lauko, kurį reikia inicijuoti, pavadinimas ir $value – reikšmė, kurią reikia nustatyti šiam laukui. Jei $property = "naudotojo vardas", metodas inicijuoja lauką $username su reikšme iš $value parametro. Kitu atveju prie $data masyvo prideda raktą $property su reikšme $value.
  • Sukūrę Narių klasę, sukuriame šios klasės objektą ir inicijuojame jo lauką $username su reikšme „fred“. Tai iškviečia __set() metodą, kuris objektui nustatys $username reikšmę. Tada lauko $vieta reikšmę nustatome į „San Franciskas“. Kadangi tokio lauko objekte nėra, metodas jį įrašo į $data masyvą.
  • Pabaigoje išimame $username ir $location reikšmes ir parodome jas puslapyje. Metodas __get() nuskaito tikrąją $username reikšmę iš esamo $username lauko ir $location reikšmę iš $data masyvo.

Kaip matote, naudodami __get() ir __set() metodus sukūrėme klasę, kurioje gali būti ir realių, ir bet kokių „virtualiųjų“ laukų. Iš kodo dalies, kurioje tam tikram laukui nustatyta reikšmė, nebūtina žinoti, ar toks laukas objekte yra, ar ne. Naudodami įprastą operatorių -> galite nustatyti lauko reikšmę arba ją perskaityti.

Pavyzdyje taip pat parodyta, kaip galite lengvai sukurti metodus, vadinamus „gavėjais“ ir „nustatymais“, kad pasiektumėte privačius laukus. Mums nereikia kurti atskirų getUsername() ir setUsername() metodų, kad galėtume pasiekti privatų lauką $username. Vietoj to sukūrėme __get() ir __set() metodus, kad galėtume valdyti šį lauką. Tai reiškia, kad mums iš viso reikia tik 2 metodų, o ne 2 metodų kiekvienam privačiam laukui.

Pastaba: Keletas žodžių apie kapsuliavimą. Naudoti privačių klasių laukus kartu su geteriais ir setteriais yra geriau nei naudoti viešuosius kintamuosius. Getters ir setters gali papildomai apdoroti duomenis, pateiktus objekto laukams ir iš jų, pavyzdžiui, patikrinti, ar reikšmė yra tinkamo formato, arba konvertuoti ją į norimą formatą. Getteriai ir nustatytojai taip pat slepia išsamią informaciją apie tai, kaip įgyvendinami klasės laukai, todėl lengviau modifikuoti klasės vidinius elementus, nes nereikia perrašyti kodo, veikiančio tos klasės objektus. Pavyzdžiui, staiga norite išsaugoti lauko reikšmę duomenų bazėje. Jei jau turėjote geterius ir seterius, tereikia juos perrašyti. Ir skambinimo kodas liks toks pat. Šis metodas vadinamas inkapsuliavimu ir yra vienas iš pagrindinių OOP privalumų.

Perkrovimo metodai naudojant __call()

Getteriai ir nustatytojai naudojami norint uždrausti prieigą prie privačių kintamųjų. Ta pačia kryptimi metodas __call() naudojamas uždrausti prieigą prie privačių metodų. Kai kodas iškviečia klasės metodą, kurio arba nėra, arba jis nepasiekiamas, automatiškai iškviečiamas metodas __call(). Štai bendra metodo sintaksė:

Viešoji funkcija __call($methodName, $arguments) ( // (veiksmai) )

Kai bandoma iškviesti nepasiekiamą klasės metodą, PHP automatiškai iškviečia __call() metodą, kuriam perduoda eilutę – iškviesto metodo pavadinimą ir perduodamų parametrų sąrašą masyve. Tada jūsų __call() metodas turės apdoroti iškvietimą tam tikru būdu ir, jei reikia, grąžinti reikšmes.

__call() metodas yra naudingas tais atvejais, kai reikia perduoti kai kurias klasės funkcijas kitai klasei. Štai paprastas pavyzdys:

Klasės narys ( privatus $naudotojo vardas; viešoji funkcija __construct($username) ( $this->username = $username; ) public function getUsername() ( grąžinti $this->username; ) ) class Topic (privatus $narys; privatus $subject ; viešoji funkcija __construct($narys, $subject) ( $this->member = $narys; $this->subject = $subject; ) viešoji funkcija getSubject() ( grąžinti $this->subject; ) viešoji funkcija __call($ metodas, $argumentai) ( return $this->member->$method($arguments); ) ) $aMember = new Member("fred"); $aTopic = nauja tema($aNarys, "Sveiki visi!"); echo $aTopic->getSubject() . “
"; // parodys "Sveiki visi!" echo $aTopic->getUsername() . "
"; // rodo "fred"

Šis pavyzdys panašus į pavyzdį, pateiktą skyriuje apie aiškų tipų nurodymą. Turime Narių klasę su lauku $username ir Temos klasę su lauku - Narių klasės objektu (straipsnio autorius) ir lauku $subject - straipsnio tema. Temos klasėje yra metodas getSubject() straipsnio temai gauti, tačiau joje nėra metodo, kuris grąžintų straipsnio autoriaus vardą. Vietoj to jis turi __call() metodą, kuris iškviečia neegzistuojantį metodą ir perduoda argumentus narių klasės metodui.

Kai jūsų kodas iškviečia $aTopic->getUsername() metodą, PHP supranta, kad tokio metodo Topic klasėje nėra. Todėl iškviečiamas __call() metodas, kuris savo ruožtu iškviečia Narių klasės metodą getUsername(). Šis metodas grąžina autoriaus vardą metodui __call(), kuris siunčia gautą reikšmę į iškvietimo kodą.

Pastaba: PHP turi kitus metodus, kurie kovoja su perkrovimu, pvz., __isset(), __unset() ir __callStatic().

Išvada

Šioje pamokoje jūs pagilinote savo žinias apie OOP PHP kalboje, išsamiau apžvelgdami sritis ir metodus. Jūs studijavote:

  • Konstruktoriai ir naikintuvai, naudingi laukams inicijuoti ir atminčiai išvalyti ištrynus objektus;
  • Statiniai laukai ir metodai, veikiantys klasės, o ne objekto lygmeniu;
  • Klasės konstantos, naudingos fiksuotoms vertėms, reikalingoms klasės lygiu, saugoti;
  • Aiškus tipų nurodymas, kuriuo galite apriboti metodui perduodamų argumentų tipus;
  • Magiški metodai __get(), __set() ir __call(), kurie naudojami norint pasiekti privačius klasės laukus ir metodus. Šių metodų įgyvendinimas leidžia sukurti „virtualius“ laukus ir metodus, kurių klasėje nėra, bet tuo pačiu galima iškviesti.

Turėdami žinias, įgytas šioje ir ankstesnėse pamokose, galite pradėti rašyti OOP. Bet tai tik pradžia! Kitoje pamokoje kalbėsime apie OOP galią – klasių gebėjimą paveldėti funkcionalumą iš kitų klasių.

Laimingo programavimo!

Ar jums patiko straipsnis? Pasidalink su draugais: