61
Osnove OOP PHP Dr Nenad Kojić, dipl. inž. Luka Lukić, struk. inž. Školska 2017/18. Danijela Nikitin, spec .stuk.inž Visoka škola strukovnih studija za informacione i komunikacione tehnologije

Osnove OOP PHP - webdizajn.ict.edu.rs · objekata klase i dalji rad sa njima prikazivao unutar jedne PHP strane Praksa je da se ovi delovi koda pišu odvojeno, i da se klasa piše

  • Upload
    others

  • View
    15

  • Download
    8

Embed Size (px)

Citation preview

Osnove OOP PHP

Dr Nenad Kojić, dipl. inž.

Luka Lukić, struk. inž.

Školska 2017/18. Danijela Nikitin, spec .stuk.inž

Visoka škola strukovnih studija za informacione

i komunikacione tehnologije

OOP

▪Objektno orijentisano programiranje je način pisanja koda, koji odgovara uređenju poslova u realnom životu.

▪Kako se zaposleni u kompaniji organizuju po kancelarijama, koji se bave nekim specifičnim stručnim poslovima (računovodstvo, pravna služba, nabavka, marketing, magacija, pogon), tako se u OOP-u srodne aktivnosti grupišu u klase.

▪Na taj način se jasno zna ko je zadužen za koje aktivnosti i gde se taj kod očekuje u ukupnom kodu.

OOP

▪Tako se postiže načelo, da nema ponavljanja, i dobija se kompaktan kod, efikasan kod i lak za održavanje.

▪Ovakav način pisanja koda se često naziva i DRY (“don’t repeat yourself”) programiranje.

▪Najčešće se kod dobro napisanog koda ažuriranje realizuje samo na jednom mestu, umesto da se usaglašava promena na mnogo mesta kao u proceduralnom kodu.

Objekat vs Klasa

Objekat vs Klasa

▪Termin objektno orijentisano programiranje baziran je nastrukturi podataka koje se naziva objekat.

▪ Međutim, termin objekat je nešto što dolazi nakondefinisanja Klase.

▪ Često se mešaju objekti i klase i to nerazumevanje praviveliki otpor u prihvatanju OOP koncepta.

▪Zato da to pojasnimo još jednom!

Klasa

▪U analogiji sa realnim životom, klasa je kao plan za izgradnjukuće.

▪Precizno je definisana dimenzija kuće, svake sobe, raspored, povezanost, pozicije vrata i prozora i sl. ali ta kućarealno ne postoji.

Objekat

▪Objekat je, sa druge strane, realno izgrađena kuća, u skladusa svim detaljima nacrta iz klase.

▪Ovakvih kuća može biti mnogo, i sve imaju zajedničkekarakteristike, jer su sve po istom planu pravljene.

Objekat

▪ Da li su kuće sa slike potpuno identične?

• Mogu da budu.

▪ Međutim, ako je neko ogradu napravio od drveta, a neko od metala, neko ima žutu kuću neko plavu, neko garnituru za sedenje na terasineko ne, nameštaj koji se razlikuje i sl. čine da ove kuće realno nisu iste.

▪ Ove nijanse u detaljima koje omogućuju razlikovanje objekata su podaciu objektu.

Objektno-orjentisano

programiranje u PHP-u

Kreiranje klasa

▪Očigledno je prvi korak kreiranje klase!

▪Kreiranje klase je pomoću rezervisane reči class

▪Primer kreiranje klase Osoba

<?php

class Osoba

{

// primer klase

}

?>

Kreiranje objekta

▪Kreiranje objekta klase se realizuje pomoću ključne reči new

▪Objekat klase se definiše proizvoljnim imenom promenljive

da bi kasnije znali kako ga oslovljavamo

$objekat = new ImeKlase;

▪Da bi se video sadržaj klase koristi se var_dump().

Primer

<?php

class Osoba

{

// primer klase

}

$objekat = new Osoba;

var_dump($objekat);

?>

Kreiranje klase Osoba

Kreiranje objekta klase Osoba

Svojstva klase

▪Rad sa svojstvima je kao i rad sa klasičnim promenljivima u

proceduralnom PHP-u.

▪ Razlika je što se može raditi samo sa onim svojstvima koja

su dodeljena objektu, i samo im se kroz njega može

pristupiti.

▪Pravila za imena svojstava su kao i pravila za imena

promenljivih

▪Preporuka je da se svojstvo definiše sa $ime-svojstva

Svojstva klase

<?php

class Osoba

{

// primer klase

public $ime = "Pera";

}

$objekat = new Osoba;

var_dump($objekat);

?>

Svojstvo klase

Pristup svojstvu

▪Obzirom da može da postoji više objekata koji su napravljeni

iz iste klase, a u svakom se može nalaziti svojstvo sa istim

imenom, bitno je naglasiti i kom tačno objektu i svojstvu se

radi.

▪U PHP-u se koristi -> da bi se definisalo kom objektu i kom

svojstvu se pristupa.

▪Obratiti pažnju da se nakon -> navodi samo naziv svojstva,

bez simbola $.

Pristup svojstvu

<?php

class Osoba

{

// primer klase

public $ime = "Pera";

}

$objekat = new Osoba;

echo $objekat->ime;

?>

Pristup svojstvu ime

Prava pristupa

▪Članovi klase mogu biti:

• Svojstva, tj. atributi

• Operacije (funkcije tj. metode)

▪Klasa i članovi klase mogu imati sledeća prava pristupa:

• public (dostupni su svima van klase, podrazumevani)

• protected (dostupni su funkcijama unutar klase i funkcijama u

klasama koje su izvedene iz posmatrane klase, ali ne i drugima koji su

van ovih struktura)

• private (dostupni samo funkcijama članicama klase)

Primer - private

<?php

class Osoba

{

// primer klase

private $ime = "Pera";

}

$objekat = new Osoba;

echo $objekat->ime;

?>

Pristup private svojstvu

izvan klase

Metode / funkcije

▪Metode su specifične funkcije neke klase

▪Specifične akcije koje će objekat moći da uradi se definišu u

klasi u njenim metodama.

▪Cilj metoda je da menjaju vrednosti atributa objekta i tako

menjaju stanje objekta

▪Kroz atribute objekta se definišu podaci koji će se u objektu

obrađivati.

Metode / funkcije

▪Operacije u klasama se najčešće definišu kao klasične

funkcije u PHP-u.

▪Kreiranje funkcije je pomoću rezervisane reči function.

▪Funkcija mora imati svoje ime, a može imati i jedan ili više

parametara.

▪Vrednosti izvršavanja funkcije mogu biti vraćene opcionom

naredbom return.

▪Ako se metoda eksplicitno ne pozove, njen rezultat rada se

ne vidi

Primer funkcije

<?php

class Osoba

{

// primer klase

public $ime = "Pera";

function pozdrav() {

echo "Zdravo. Ja sam Pera!";

}

}

$objekat = new Osoba;

$objekat->pozdrav();

?>

Kreiranje funkcije pozdrav()

koja ne vraća ništa, već

samo ispisuje tekst

upotrebom funkcije echo.

Pozivanje funkcije

pozdrav()

Primer funkcije sa parametrima

<?php

class Osoba

{

// primer klase

public $ime = "Pera";

function pozdrav($prezime) {

echo "Zdravo. Ja sam Pera ".$prezime."!";

}

}

$objekat = new Osoba;

$objekat->pozdrav("Peric");

?>

Funkcija koja prihvata

jedan parametar

Primer funkcije - return

<?php

class Osoba

{

// primer klase

public $ime = "Pera";

function pozdrav($prezime) {

return "Zdravo. Ja sam Pera ".$prezime."!";

}

}

$objekat = new Osoba;

echo $objekat->pozdrav("Peric");

?>

Kreiranje funkcije pozdrav()

koja vraća neku vrednost.

Kako funkcija vraća vrednost, dobijeni

rezultat treba ispisati sa echo

Funkcija sa opcionim parametrima▪Opcioni parameter se mora nalaziti na kraju liste argumenata i

imati podrazumevanu vrednost koja je najčešće null ili prazan

string.

<?php

class Osoba

{

// primer klase

public $ime = "Pera";

function pozdrav($ime, $prezime = null) {

echo "Zdravo. Ja sam Pera ".$prezime."! <br/>";

}

}

$objekat = new Osoba;

$objekat->pozdrav("Pera", "Peric");

$objekat->pozdrav("Pera");

$objekat->pozdrav(); // greska - $ime je obavezno

?>

Funkcija čiji je obavezan

prvi parametar, a drugi je

opcioni

$this

▪Kao i u većini drugih jezika, i PHP-u je promenljiva

$this rezervisana za ukazivanje na na tekući objekat

▪Pristup atributu tekućeg objekta je pomoću simbola ->

$this

<?php

class Osoba

{

// primer klase

public $ime = "Pera";

private $imePrezime;

function pozdrav($prezime){

$this->imePrezime = $this->ime . " " . $prezime;

return "Zdravo. Ja sam ". $this->imePrezime;

}

}

$objekat = new Osoba;

echo $objekat->pozdrav("Peric");

?>

Dodela vrednosti svojstvu

imePrezime tekućeg objekta

Dohvatanje vrednosti svojstva

imePrezime tekućeg objekta

Primer<?php

class Osoba

{

public $ime = "Pera";

private $zanimanje = "Student";

public function setZanimanje($zanimanje){

$this->zanimanje = $zanimanje;

}

public function getZanimanje(){

return $this->zanimanje;

}

}

$objekat = new Osoba;

echo $objekat->getZanimanje()."<br/>";

$objekat->setZanimanje("Programer");

echo $objekat->getZanimanje();

?>

Statičke promenljive i metode

▪Statičke promenljive se mogu inicijalizovati na tačno jednom

mestu u klasi i one su zajedno sa statičkim metodama

zajedničke za sve objekte neke klase.

▪Statičke metode se mogu pozivati iz objekta neke klase, ali

mogu se pozivati i samostalno tako što se pre metode

navede ime klase sa dve dvotacke.

Statičke promenljive i metode

▪Pozivanje statičkih svojstava i metoda unutar klase:

❖ self::svojstvo;

❖ self::metoda();

▪Pozivanje statičkih svojstava i metoda izvan klase:

❖ ImeKlase::svojstvo;

❖ ImeKlase::metoda();

Primer

<?php

class Krug

{

public static $pi = 3.14;

public static function vrati(){

return self::$pi;

}

public static function vrati1(){

return self::vrati();

}

}

echo Krug::$pi;

echo Krug::vrati();

?>

Konstruktori

▪Konstruktorom se pravi novi objekat

▪Sintaksno, konstruktor se definiše kao i druge funkcije, ali je

ime funkcije identično imenu klase

class Osoba

{

function Osoba($a)

{

echo(“Realizovan konstruktor sa parametrom $a!”);

}

}

Konstruktori

▪Konstruktori omogućavaju da se prilikom kreiranja objekta

istovremeno izvrši inicijalizacija svojstava u objektu

▪ Inicijalno PHP ne podržava preklapanje funkcija, pa moraju

imati jedinstvena imena

Instanca objekta sa konstruktorom<?php

class Osoba

{

public $ime;

public function Osoba($a) {

$this->ime = $a;

echo "Realizovan konstruktor sa parametrom $a!<br/>";

}

}

$objekat1 = new Osoba("Pera");

$objekat2 = new Osoba("Mika");

?>

▪ Kako se konstruktor poziva svaki put kada se pravi objekat, rezultat će

biti:

Pristupna funkcija

▪U slučaju da se podacima pristupa van klase, poželjno je

napisati pristupnu funkciju

<?php

class Osoba

{

public $ime = "Pera";

public function setIme($ime) {

$this->ime = $ime;

}

public function getIme() {

return $this->ime;

}

}

?>

Kopiranje i uništavanje objekta

▪ Kopiranje objekta se vrši sa rezervisanom reči clone

$objekat_copy = clone $prvi_objekat;

▪ Uništavanje objekta se vrši funkcijom unset()

unset($prvi_objekat);

$prvi_objekat->ispis(); //greska

Nasleđivanje

▪ Nasleđivanje klasa se definiše rezervisanom rečju extends.

▪ U klasi koja nasleđuje, dostupna su sva svojstva i metode iz natklase,

koje nisu private.

▪ Ukoliko je klasa Zaposleni nasledila klasu Osoba, tada se označava

kao:

class Zaposleni extends Osoba

{

public $plata;

function opis($vrednost) {

$this->plata = $vrednost;

echo this->plata;$

}

}

Primer – nasleđivanje<?php

class Osoba {

public $ime;

public function Osoba(){

echo "Osoba je kreirana <br/>";

}

}

class Zaposleni extends Osoba

{

public $plata;

function opis($ime, $vrednost){

$this->ime = $ime;

$this->plata = $vrednost;

echo $this->ime ." - ".$this->plata;

}

}

$zaposleni = new Zaposleni();

$zaposleni->opis("Pera", 5000);

?>

Svojstvo dostupno

iz natklase

Primer – nasleđivanjeclass proba

{

var $atribut1; // var = public

var $atribut2;

function obrada1($a)

{

$this->atribut1 = $a;

echo $this->atribut1."<br/>";

}

}

class proba_2 extends proba

{

var $atribut3;

var $atribut4;

function obrada2($b)

{

$this->atribut3 = $b;

echo $this->atribut3."<br/>";

}

}

$novi = new proba_2;

$novi->obrada1(111); // iz proba

$novi->atribut1 = 222; // iz proba

$novi->obrada2(333); // iz proba_2

$novi->atribut3 = 444; // iz proba_2

$novi = new proba;

$novi->obrada1(111);

$novi->atribut1 = 222;

$novi->obrada2(333);

$novi->atribut3 = 444;

Overriding metoda

▪ Često se kod izvođenja klasa nameće potreba da se promeni

način rada nekog metoda u baznoj klasi.

▪ Ako se u baznoj klasi Osoba definiše metod setIme i koji radi

neki posao, moguće se u klasi Zaposleni, koja je izvedena iz

klase Osoba, kreirati metod sa istim imenom kao u nadklasi, tj.

metod setIme koji radi potpuno drugi posao.

▪ Na ovaj način smo override-ovali metod setIme u klasi Osoba,

pravljenjem istog metoda u izvedenoj klasi.

Primer – override bazne klase

class Osoba {

protected $ime;

public function setIme($ime){

$this->ime = $ime;

}

public function getIme(){

return $this->ime;

}

}

class Zaposleni extends Osoba {

public function setIme($ime) {

$this->ime = strtoupper($ime);

}

}

Testiranje rezultata:

$zaposleni = new Zaposleni();

$zaposleni->setIme("Pera");

echo $zaposleni->getIme();

Overriding metoda

▪ U prethodnom primeru je override-ovan metod nadklase, tj.

bazne klase

▪ Isti proces može se uraditi i sa metodom u izvedenoj klasi

▪ U ovom primeru to bi značilo da se override-uje metod setIme u

klasi Zaposleni, koja je izvedena iz klase Osoba.

▪ Za ovo se koristi Osoba::setIme($ime);

▪ I tako se pristupa baznoj klasi Osoba tj. njenoj verziji metoda

setIme.

Primer – override izvedene klase

class Osoba {

protected $ime;

public function setIme($ime){

$this->ime = $ime;

}

public function getIme(){

return $this->ime;

}

}

class Zaposleni extends Osoba {

public function setIme($ime) {

Osoba::setIme($ime);

}

}

Testiranje rezultata:

$zaposleni = new Zaposleni();

$zaposleni->setIme("Pera");

echo $zaposleni->getIme();

Overriding metoda

▪ U prethodnom primeru korišćeni su :: za omogućavanje PHP kodu da

traži određeni metod van klase u kojoj se realizuje.

▪ Tako je oznaka Osoba::setIme() ukazala da se traži metod koji se zove

setIme() u klasi “Osoba”

▪ Pored ovog načina, postoji i kraći način pisanja kojim se postiže isti

efekat sa nadklasom.

▪ Ovo je omogućeno korišćenjem reči parent

parent::setIme($ime);

Primer – override izvedene klase

class Osoba {

protected $ime;

public function setIme($ime){

$this->ime = $ime;

}

public function getIme(){

return $this->ime;

}

}

class Zaposleni extends Osoba {

public function setIme($ime) {

parent::setIme($ime);

}

}

Testiranje rezultata:

$zaposleni = new Zaposleni();

$zaposleni->setIme("Pera");

echo $zaposleni->getIme();

Način pisanja koda

▪Do sada se kod koji pripada klasama kao i kod za kreiranje

objekata klase i dalji rad sa njima prikazivao unutar jedne PHP

strane

▪Praksa je da se ovi delovi koda pišu odvojeno, i da se klasa

piše u posebnom fajlu, koji se uključuje po potrebi u drugu PHP

stranu koja treba da koristi rad klasa.

▪Obično se fajl u kome se nalaze sve klase naziva biblioteka

klasa tj. skup klasa.

Primer – kod u jednom fajlu<?php

class Klasa_A{

public $podatak;

public function ispis() {

echo $this->podatak . "<br/>";

}

}

// Kreiranje objekta kao instance Klasa_A

$objekat = new Klasa_A();

// Definisanje vrednosti $podatak unutar klase

$objekat->podatak = "Ovo je prvi sadrzaj.";

// Kreiranje drugog objekta kao instance Klasa_A i definisanje druge vrednosti

$drugi_objekat = new Klasa_A();

$drugi_objekat->podatak = "Ovo je drugi sadrzaj.";

// Koriscenje metoda ispis klase Klasa_A

$objekat->ispis();

$drugi_objekat->ispis();

?>

Primer – kod u zasebnim fajlu

▪ Kod klase treba stavili u poseban php fajl koji možemo nazvati

class_lib.php i uključiti ga u stranicu index.php, u head sekciju,

pomoću

<?php include("class_lib.php"); ?>

class_lib.php

<?php

class Klasa_A{

public $podatak;

public function ispis(){

echo ($this->podatak . "<br/>");

}

}

?>

index.php<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8" /><title>OOP PHP</title>

<?php include("class_lib.php"); ?>

</head><body>

<?php

// Kreiranje objekta kao instance Klasa_A

$objekat = new Klasa_A();

// Definisanje vrednosti $podatak unutar klase

$objekat->podatak = "Ovo je prvi sadrzaj.";

// Kreiranje drugog objekta kao instance Klasa_A i definisanje

druge vrednosti

$drugi_objekat = new Klasa_A();

$drugi_objekat->podatak = "Ovo je drugi sadrzaj.";

// Koriscenje metoda ispis klase Klasa_A

$objekat->ispis();

$drugi_objekat->ispis();

?> </body></html>

Poređenje objekata<?php

include "class_lib.php";

// Kreiranje objekta kao instance Klasa_A

$prvi_objekat = new Klasa_A();

// Definisanje vrednosti $podatak unutar klase

$prvi_objekat->podatak = "Ovo je prvi sadrzaj.";

// Kreiranje drugog objekta kao instance Klasa_A i definisanje druge vrednosti

$drugi_objekat = new Klasa_A();

$drugi_objekat->podatak = "Ovo je drugi sadrzaj.";

// Koriscenje metoda ispis klase Klasa_A

$prvi_objekat->ispis();

$drugi_objekat->ispis();

Poređenje objekata - nastavak// Poredjenje objekata sa ==

$poredjenje_objekata = ($prvi_objekat ==

$drugi_objekat);

if($poredjenje_objekata) {

echo("Provera 1 - Objekti su isti!");

}

else{

echo("Provera 1 - Objekti nisu isti!

<br/>");

}

// Promena vrednosti drugog objekta

$drugi_objekat->podatak = "Ovo je prvi

sadrzaj.";

$poredjenje_objekata = ($prvi_objekat ==

$drugi_objekat);

if($poredjenje_objekata) {

echo("Promena - Objekti su isti!<br/>");

}

else {

echo("Promena - Objekti nisu isti!");

}

// Poredjenje dva objekta sa === (po tipu,

referenci, vrednosti..)

$poredjenje_objekata = ($prvi_objekat ===

$drugi_objekat);

if($poredjenje_objekata) {

echo("Provera 2 - Objekti su isti!<br/>");

}

else {

echo("Provera 2 - Objekti nisu isti!");

}

?>

Magic Methodi

Magic Methodi

▪ PHP omogućava veliki broj “magičnih metoda” tj. posebno

kreiranih metoda koje se pozivaju kada se neka specifična

akcija desi sa objektom.

▪ Ovo omogućava programeru da se relativno lako obave vrlo

korisni poslovi.

▪ http://php.net/manual/en/language.oop5.magic.php

Magic Methodi

➢ __construct()

➢ __destruct()

➢ __clone()

➢ __toString()

➢ __get()

➢ __set()

➢ __isset()

➢ __unset()

Magic Methodi

➢ __sleep()

➢ __wakeup()

➢ __invoke()

➢ __call()

➢ __callStatic()

➢ __set_state()

➢ __debugInfo()

__construct()

▪ Kreiranje konstruktora kao funkcije sa imenom klase

function ImeKlase() { … }

predstavlja stariji način i od PHP verzije 5.3.3 se smatra regularnom

funkcijom.

▪ U PHP 7.0 ova sintaksa je “deprecated” i u budućnosti će biti

potpuno izbačena iz upotrebe.

▪ Nova notacija pisanja konstruktora klase, jeste korišćenje magic

metode

__construct()

__construct()

▪ Konstruktori roditelja, tj. natklase, se ne pozivaju implicitno

ukoliko izvedena klasa ima definisan konstruktor.

▪ Kako bi se pozvao konstruktor natklase, neophodno je u telu

konstruktora izvedene klase napisati

parent::__construct()

▪ Ako izvedena klasa nema definisan konstruktor, naslediće od

roditelja kao i sve metode (ukoliko nije privatan).

Primer - __construct()class Osoba {

protected $ime;

function __construct($ime){

$this->ime = $ime;

}

}

class Zaposleni extends Osoba {

protected $plata;

function __construct($ime, $plata){

parent::__construct($ime);

$this->plata = $plata;

}

public function ispis(){

return $this->ime.' - '.$this->plata;

}

}

$zaposleni = new Zaposleni("Pera", 5000);

echo $zaposleni->ispis();

__toString()

▪ Metod __toString() omogućava klasi da odluči kako će se

ponašati kada bude tretirana kao string.

▪ Na primer:

$objekat = new Zaposleni();

echo $objekat;

▪ Ovaj metod mora da vraća string, inače će se javi

E_RECOVERABLE_ERROR greška.

Primer - __toString()class Osoba {

protected $ime;

function __construct($ime){

$this->ime = $ime;

}

}

class Zaposleni extends Osoba {

protected $plata;

function __construct($ime, $plata){

parent::__construct($ime);

$this->plata = $plata;

}

public function __toString(){

return $this->ime.' - '.$this->plata;

}

}

$zaposleni = new Zaposleni("Pera", 5000);

echo $zaposleni;

Osnove OOP PHP

Dr Nenad Kojić, dipl. inž.

Luka Lukić, struk. inž.

Školska 2017/18. Danijela Nikitin, spec .stuk.inž

Visoka škola strukovnih studija za informacione

i komunikacione tehnologije