[ zgas @ 18.06.2007. 14:14 ] @
Poceo sam da radim sa klasama pa sam upao u problem.

Koristim specijalnu klasu za obradu posebnih podataka.
Ocu da kazem da klasa nije neka opsta (za bilo koji projekat) vec vrlo specificna.

E sada da bi pristupio bazi i izvrsio obicne querije (u toj mojoj specificnoj klasi), zelim da koristim drugu opstu klasu posebno namenjenu za tu namenu (rad sa bazom).

Pojma nemam da li je tomoguce?
Ispada da hocu da koristim klasu u klasi...
Pokusavao sam nesto ali sta god da uradim - skript ne radi.

Imate li savet - pomoc?
Kako da resim ovaj problem?

Hvala vam mnogo unapred.
[ centaur @ 18.06.2007. 17:52 ] @
Zašto ta specijalna klase jednostavno ne nasledi tu klasu za rad sa bazom?
[ zgas @ 18.06.2007. 20:17 ] @
Da, shvatio sam da je to resenje.

Ali ne znam da ga upotebim.

Znam da mogu u jednom skriptu da pozovem klasu koja je nasledila drugu klasu i da to koristim.

Interesuje me da li u samoj klasi koja nasledjuje, mogu da pozovem sa $a = new calass(); ?

Mozda lupam, ali kad ne znam....

[Ovu poruku je menjao zgas dana 18.06.2007. u 21:41 GMT+1]
[ Miroslav Ćurčić @ 18.06.2007. 21:35 ] @
Ne moraš,
shvati klasu kao tip promenljive, nešto kao integer ili string, samo što klasa ima mogućnost da lageruje funkcije unutar svoje definicije.

Promenljivu "oživiš" tako što joj dodeliš memoriju, tj rezervišeš u memoriji prosor za nju uz pripadajuće ime promenljive, npr. $A='S'. Ovde je oživljena promenljiva A i dodeljen joj 1 bajt memorije (laički).
Klasu takođe moraš "oživeti" ali se to radi sa: $MojaKlasa= new MyClass(); (žargon: instanciranje klase) ali se svodi na isto.

Takođe svaka klasa može da ima "roditelja" tj klasu iz koje si je nasledio, ali pošto je ona sastavni deo nove klase nema potrebe (a i ne može) da se dodatno instancira.

Naravno možeš unutar klase instacirati druge klase koje nemaju veze s trenutnom.
[ zgas @ 29.11.2007. 10:52 ] @
Da li je moguće koristiti neki DBlayer (ADOdb ili PearDB) u nekoj klasi, ali ne na nacin da ta klasa jeste prosireni (extends) DB layer.

Znači NE OVAKO:
Code:

class Kalkulacija extends ADOdb { ... }


Ovo mi je bitno jer zelim da mi klasa 'Kalkulacija' ostane slobodna za nasledjivanje (extends) druge klase, a ne klase DBlayer kojeg ipak treba da koristi za pristup podacima.

Molim vas za pomoc.
[ devil.x3m @ 11.05.2009. 10:02 ] @
Da ne bi otvarao novu temu, pitacu ovde jer nije bas najbolje odgovoreno.


Dakle kao sto je covek na pocetku pitao kako komunicirati izmedju dve ili vise klasa?


Konkretan primer:


Imam recimo 3 (ili vise) klasa.

Prva je klasa za rad sa bazom u kojoj recimo imam funkciju za konekciju na bazu.


class BAZA {
function konektuj() {
$db = mysqli_connect ( ... );
if ( mysqli_connect_errno() ) {
echo 'Error: could not connect to database';
exit;
}
return $db;
}
}

Druge dve klase su recimo:

class A {
function login {}
function register {}
...
}
class B {
function edit {}
function delete {}
function insert {}
...
}


Dakle kako da u funkcijama iz klasa A i B pozivam konekcju iz klase BAZA?

Da li i A i B moraju da naslede BAZU ili se u svakoj funkciji tih klasa mora instancirati klasa BAZA?


Jel moze neko na konkretnom primeru vezanom za gore moj primer da mi objasni kako se to izvodi?


Hvala! :)
[ Tudfa @ 11.05.2009. 10:31 ] @
Da bi napravio objekat neke klase prethodno ti je potrebna njena definicija u tom fajlu u kome radiš.

Code:

class Baza
{
    public function konektuj(){echo 'Pozvan konektuj() klase Baza<br>';}
}

class A
{
    public function login()
    {
        echo 'Pozvan login() klase A<br>';
        $baza = new Baza();
        $baza->konektuj();
    }
    public function register(){echo 'Pozvan register() klase A<br>';}

}
class B
{
    public function edit(){echo 'Pozvan edit() klase B<br>';}
    public function delete(){echo 'Pozvan delete() klase B<br>';}
    public function insert(){echo 'Pozvan insert() klase B<br>';}
}

$a = new A();
$a->login();


dobićeš rezultat:

Code:

Pozvan login() klase A
Pozvan konektuj() klase Baza


Ovo ti je jedan od načina, sve zavisi šta ti je cilj i šta ti odgovara.
[ Mister_rap @ 11.05.2009. 10:53 ] @
Ili da prenosis/kreiras instancu klase za rad sa bazom preko konstruktora u klasama u kojim ti je potrebna.
Nesto ovako:

Code:

class A {
    private $db;

    public function __construct($db) {
        $this->db=$db;
        //ili ovako nesto $this->db=new Baza();
    }

    public function login(){
        echo 'Pozvan login() klase A<br>';
        $this->db->konektuj();
    }
}


[Ovu poruku je menjao Mister_rap dana 11.05.2009. u 12:45 GMT+1]
[ devil.x3m @ 12.05.2009. 10:42 ] @
Hvala na odgovorima, koristio sam drugi primer sa konstruktorom. :)
[ centaur @ 12.05.2009. 12:28 ] @
Dobra praksa za "prenosenje" objekata je registry pattern

PS Prvi odgovor na ovu temu je totalna glupost ;)
[ Nikola Poša @ 12.05.2009. 14:13 ] @
Slažem se, ali mogao si da daš i neki bolji primer za registry pattern. Obično je ta registry klasa rađena i po singleton pattern-u, kako ne bi morala da se svaki put instancira, npr.:
Code:

class Registry
{
    private static $instance = null;
    
    protected $registry = array();

    public static function getInstance()
    {
        if (self::$instance=== null) {
           self::$instance= new Registry;
        }

        return self::$instance;
    }

    public static function get($index)
    {
        $instance = self::getInstance();

        return $registry[$index];
    }

    public static function set($index, $value)
    {
        $instance = self::getInstance();
        $registry[$index] = $value;
    }
}

Čak je možda još i bolja praksa da se cela ta klasa izvodi iz ugrađene PHP-ove klase ArrayObject, pa onda nema potrebe za tim poljem $registry, već bi se za unos/dohvatanje koristile nasleđene f-je offsetSet() i offsetGet(). Na tom prinicipu radi Registry klasa iz Zend_Framework-a.
[ centaur @ 12.05.2009. 14:34 ] @
Iskreno, totalno sam povrsno bacio pogled na prva dva linka na googletu i ovaj je bio bolji od ta dva ( povrsno gledano ;) ).
Tako je, dobro je da implementira singleton pattern.

[ Tudfa @ 12.05.2009. 14:55 ] @
Citat:
centaur: Dobra praksa za "prenosenje" objekata je registry pattern

PS Prvi odgovor na ovu temu je totalna glupost

U svakom slučaju registry patern !! Radi posao mnogo bolje nego ovaj predlog:

Citat:
centaur: Zašto ta specijalna klase jednostavno ne nasledi tu klasu za rad sa bazom?

E sad, i ovo nasledjivanje može nekad da se upotrebi, ali ne baš u ovakvom kontekstu.

Neki primer gde ima nasledjivanja kod klasa za rad sa bazama podataka bi recimo bio da imamo apstraktnu klasu dbal(database abstraction layer)
onda iz nje izvodimo klase za rad sa specificnim tipovima baza podataka mysql, mssql, firebird...

Citat:
Tudfa 
Ovo ti je jedan od načina, sve zavisi šta ti je cilj i šta ti odgovara.


I da se nadovežem na ovo, jer ovaj moj predlog isto nije najsjajnije rešenje kad se radi sa bazom, ali je koristilo zbog primera.
Bolja varijanta je ova što je Mister_Rap predlozio jer se tada ne otvara nova konekcija svaki put kad se pozove metod konektuj.

Inače kao što je Nikola napomenuo za registry klasu, singleton patern mozes da koristiš i za database klasu. Ja sam od skoro počeo
da je koristim i svidja mi se jer otvorim konekciju na početku i posle koristim samo getInstance() da bi dobio instancu db klase.

Evo kako bi u osnovi izgledala database klasa sa singleton paternom:
Code:
<?php
class SingletonDatabase
{
    private static $instance;
    private $mysqli   = null;
    
    private function __construct()
    {
        //ovde samo otvoris konekciju 
    }
    
    private function __clone(){}
    
 
    public static function getInstance()
    {
        if (!self::$instance instanceof self)
        {
              self::$instance = new self;
        }
        return self::$instance;
      }

       //ovde posle definišeš funkcije za izvršavanje upita

    public function __destruct(){if($this->mysqli){$this->mysqli->close();}}
}
?>
[ centaur @ 12.05.2009. 16:58 ] @
^Vec sam rekao da je prvi odgovor na temu totalna glupost.
To je bilo bezmalo pre dve godine. Moj pogled na OOP se mnoooogo promenio od tad.
[ Tudfa @ 12.05.2009. 17:31 ] @
@centaur
Jeste iz 2007. godine odgovor znam to i pratim tvoje postove iz kojih često naučim. To što sam hteo je da navedem primer gde se bolje moze iskoristi ono što je navedeno tada.