1. Főoldal
  2. Cikkek
  3. Dev
  4. [OOPWeb] Változók és láthatóságuk

[OOPWeb] Változók és láthatóságuk

Dev

Az előző részekben megtudtuk, mi az az objektum orientált programozás, majd létrehoztuk az első osztályunkat is - ha te esetleg mindezt még nem tetted meg, akkor nem véletlenül volt a bevezetőben a két link is elrejtve, nyugodtan olvasd el az előző részeket is! Viszont a mostan cikkben folytatjuk a programozást, és a 21. század változó világával megküzdve változókat fogunk deklarálni - na meg szó lesz a láthatóságról is.

Hogy mi a változó, azt már a nem objektum orientált programozási tapasztalatunkból is tudhatjuk - sőt, az előző részekben már használtunk is változókat függvények bemeneti paramétereként. Úgyhogy felmerülhet a kérdés: miről is fog szólni ez a cikk? Nos, először is, nézzük, miről nem (az egyszerűség kedvéért vegyük elő az előző cikkünk mintakódját, és azt folytassuk.):

class login{
    public function __construct(){
       //do something
       echo 'Én egy új példánya vagyok a login osztálynak!';
    }
     
    public function addNewUser($username){
       //do something
       echo 'Új felhasználó, '.$username.'!';
       $uid = uniqid();
       return array('success'=>true,'uid'=>$uid);
    }
 
    public function login($username){
       //do something
       echo 'hello, kedves '.$username.'!';
       return true;
    }
 
    public function register($username){
       //do something
       $data = $this->addNewUser($username);
       if($data['success']){
           echo 'Sikeres regisztráció!';
       }
    }
 
    public function signout(){
       //do something
       echo 'Sikeres kijelentkezés!';
    }
 
    public function __destruct(){
       //do something
       echo 'Bye bye World!';
    }
}
 

Tehát a fenti kódban található változókról nem lesz szó a mostani cikkben: nem fogunk foglalkozni a függvények bemeneti paramétereivel, a visszatérési értékekkel, és a függvényekben deklarált változókkal sem - ugyanis ezek használata az eddig megszokott módon történik. Akkor pedig miről lesz szó? Az osztályon belüli változókról!

Ezek olyan változók, melyek valamilyen módon az osztályhoz - illetve annak egy példányához - tartoznak. Nézzünk is rá egy példát:

class login{
 
    public $uid = null;
 
    public function __construct(){
       //do something
       echo 'Én egy új példánya vagyok a login osztálynak!';
    }
     
    public function addNewUser($username){
       //do something
       echo 'Új felhasználó, '.$username.'!';
       $uid = uniqid();
       return array('success'=>true,'uid'=>$uid);
    }
 
    public function login($username){
       //do something
       $this->uid = uniqid();
       echo 'hello, kedves '.$username.'!';
       return true;
    }
 
    public function register($username){
       //do something
       $data = $this->addNewUser($username);
       if($data['success']){
           $this->uid = $data['uid'];
           echo 'Sikeres regisztráció!';
       }
    }
 
    public function signout(){
       //do something
       echo 'Sikeres kijelentkezés!';
    }
 
    public function checkIsLogedIn(){
        return (!is_null($this->uid));
    }
 
    public function __destruct(){
       //do something
       echo 'Bye bye World!';
    }
}
 

A fenti példában az osztályhoz létrehoztunk egy uid nevű változót, mely alap esetben a null-t, viszont belépés után a felhasználó ID-jét tartalmazza. Később a checkIsLogedIn függvényben ezt ellenőrizve döntöttük el, hogy a felhasználó be van-e lépve, vagy nincs. 

A példából már látszik is a különbség egy sima, függvényben lévő változóhoz képest: a függvényben lévő társaikkal ellentétben az osztályban lévő nem kötődik 1-1 függvényhíváshoz, nem szűnik meg a függvény lefutása után, az objektum létezéséig végig megmarad. A globális változókkal ellentétben viszont ezek a változók nem "csak úgy" léteznek, hanem egy logikai egységen belül helyezkednek el. Nézzük is meg, hogy mi történik, ha egy (a fenti) osztályból több példányt (objektumot) hozunk létre:

$user1 = new login();
$user2 = new login();
$user3 = new login();
 
$user1->register('vmarci21');
$user3->register('kisspista');
 
print_r ($user1->checkIsLogedIn());
print_r ($user2->checkIsLogedIn());
print_r ($user3->checkIsLogedIn());

print_r ($user1->uid);
print_r ($user2->uid);
print_r ($user3->uid);
 

A fenti példában létható, hogy csak egy osztályt, több példányban létrehozva azok teljesen különálló elemek lesznek - az $uid értéke 3 különböző érték volt a 3 különböző, de ugyanabból az egy osztályból létrehozott objektum esetében is. Ezekből következik az is, hogy az objektumban lévő változók használata esetén, (ellentétben a globális társaiknál), nem kell attól félni, hogy egy teljesen másik kódrészlet összeomlasztja a kódunkat, csak azért, mert két változót pont ugyanúgy neveztek el valahol máshol is.

Mindezek után viszont érdemes még egy dolgot megismerni: ez pedig a láthatóság. Bár már most is megtudtuk csinálni, hogy véletlenül a mi kódunktól teljesen független kódrészlet ne tudja felülírni a változóinkat, (hiszen nem lehet névütközés két külön objektum között), de szándékosan még mindig meg lehet tenni:

$user1 = new login();
 
$user1->register('vmarci21');
 
print_r ($user1->checkIsLogedIn());
print_r ($user1->uid);
 
$user1->uid = 10;

print_r ($user1->checkIsLogedIn());
print_r ($user1->uid);
 
$user1->uid = null;

print_r ($user1->checkIsLogedIn());
print_r ($user1->uid);
 

Természetesen ez nem a legjobb futási mód - a felhasználó ID-je csak belépés vagy regisztráció által kéne legyen módosítható - semmi szükség rá, hogy az a változó ezen függvények futtatása nélkül új értéket vegyen fel. Természetesen erre lehet azt mondani, hogy nincs evvel semmi baj, nem fog senki ilyet csinálni - de inkább érdemes megelőzni a bajt (és a több órán, napon át tartó "miért nem úgy működik a kódom, ahogy én akarom?" felkiáltású elfoglaltságot), és használhatjuk a változók, illetve a függvények esetében is a láthatóságot.

Összesen 3 lehetőségünk van:

  • public - nyilvános, publikus; az az bárhonnan, bármikor elérhető és módosítható
  • private - privát; az az csak az adott objektumon (osztályon) belül elérhető
  • protected - védett; csak a származtatott osztályokból érhető el

Az első két lehetőség egyértelmű hatást ér el, a harmadikról pedig még a későbbiekben is lesz szó - úgyhogy most nézzük újra az eddig is írt osztályunkat, és módosítsuk ezeknek megfelelően:

class login{
 
    private $uid = null;
 
    public function __construct(){
       //do something
       echo 'Én egy új példánya vagyok a login osztálynak!';
    }
     
   private function addNewUser($username){
       //do something
       echo 'Új felhasználó, '.$username.'!';
       $uid = uniqid();
       return array('success'=>true,'uid'=>$uid);
    }
 
    public function login($username){
       //do something
       $this->uid = uniqid();
       echo 'hello, kedves '.$username.'!';
       return true;
    }
 
    public function register($username){
       //do something
       $data = $this->addNewUser($username);
       if($data['success']){
           $this->uid = $data['uid'];
           echo 'Sikeres regisztráció!';
       }
    }
 
    public function signout(){
       //do something
       echo 'Sikeres kijelentkezés!';
    }
 
    public function checkIsLogedIn(){
        return (!is_null($this->uid));
    }
 
    public function __destruct(){
       //do something
       echo 'Bye bye World!';
    }
}
 

És ezek után nézzük meg újra ennek a kódnak az eredményét:

$user1 = new login();
 
$user1->register('vmarci21');
 
print_r ($user1->checkIsLogedIn());
print_r ($user1->uid);
 
$user1->uid = 10;

print_r ($user1->checkIsLogedIn());
print_r ($user1->uid);
 
$user1->uid = null;

print_r ($user1->checkIsLogedIn());
print_r ($user1->uid);
 

A végeredmény meglepően (?) más lett ez esetben, igaz? Végezetül már csak a következő rész tartalmára térnék ki:

A következő rész varázslatos lesz - ugyanis megismerkedhetünk majd a Magic Methods-nak elnevezett függvényekkel, melyek után egy kicsit bonyolultabb (de mégsem túlságosan bonyolult) dologgal, az öröklődéssel is találkozhatunk - melyek után elmondhatjuk magunkról, hogy a PHP objektum orientált lehetőségeinek leggyakrabban használt, és legfontosabb részeit megismertük - de azért lesz még néhány, a témához köthető ismeretanyag, és egy blog felépítése sem maradhat el a későbbiekben! 

vmarci21 profilképe
Veszter Márton @vmarci21 +531 Weblap fejlesztő, az IntoMedia tagja. PHP, JavaScript és MySql témák mellett érdekli a Windows, Linux disztribúciók, Android fejlődése, az IT biztonság, és az újdonságokat felmutató IT termékek.
0 hozzászólás
Hozzászóláshoz jelentkezz be vagy Regisztrálj!