[ alfa-pro @ 10.03.2013. 14:53 ] @
E ovako nisam siguran ali video sam u nekim frameworkovima da instacira neku klasu u jednom fajlu i onda mu je dostupan u ostalim klasama. Da pojasnim.

Na primer ja u index.php imam objekat $FC i $cfg ($FC je front kontroler a $cfg je instanca koja mi ucitava cofiguracionu klasu sa podesavanjima).

Code:

spl_autoload_register('Loader::autoloader');
spl_autoload_register('Loader::Config');

$FC   = new FrontController();
$cfg   = new BaseConfig();


E sada ja imam LOG klasu koju sam pravio i koja u konstruktoru zahteva da joj definisem putanju log fajla, format datuma, ime i ekstenziju.
Evo kako izgleda konstruktor moj LOg klase:

Code:

    public function __construct()
    {
        if ($this->get_status() == true) {
        
            // Configuration 
            $this->set_path('logs/');                  // Directory name <full path>
            $this->set_date_format('Y-m-d');     // Date format
            $this->set_extension('.txt');            // Log file extension
            $this->set_mode('a');                    // Writig mode
            $this->set_prefix('log_');                // File name prefix example(log_2012-06-26)
        }
        
        Log::log_message('debug','Log class initialized');
    }


Sta ja zelim sada: Vidite ovo $this->set_path('logs/'); e umesto tog 'logs/' da pozovem property bez ponovnog kreiranja $cfg objekta.
Ovako nesto:

Code:

    public function __construct()
    {
        if ($this->get_status() == true) {
        
            // Configuration 
            $this->set_path($cfg->logPath);                         // Directory name <full path>
            $this->set_date_format($cfg->logDateFormat);     // Date format
            $this->set_extension($cfg->logExtension);            // Log file extension
            $this->set_mode($cfg->logMode);                      // Writig mode
            $this->set_prefix($cfg->logPrefix);                      // File name prefix example(log_2012-06-26)
        }
        
        Log::log_message('debug','Log class initialized');
    }

Ali da nemoram da u konstruktori dodajem $cfg = new BaseCOnfig();
Kako da izvedem da samo na jednom mestu napravim instancu i da taj objekat bude dostupan u svim mojim ostalim klasama da nemoram stalno da kreiram nove instance...

Hvala
[ dakipro @ 10.03.2013. 16:23 ] @
ovako instant mi pada napamet da ili napravis CFG static posto pretpostavljam da uglavnom citas vrednosti iz tog objekta ili da ga prosledis konstruktoru, mozda kroz neki interfejs kolko da ih ne couplujes previse
[ alfa-pro @ 10.03.2013. 17:59 ] @
To je i meni palo na pamet. Ali pogledaj kako sam ja to sada nekako smislio samo sto ovo moje resenje zahteva da svaka klasa mora da nasledi odredjenu klasu npr Application.

Evo primer Application klase:

Code:

class Application {

     // Constructor
 
     public function __construct() {
             $this->_initialize_super_object();
             log_message('debug','Application class initialized.);
      }

    // Super Object
   // Run as one big super object.

    public function _initialize_super_object() {
         $object = array('cfg' => 'baseConfig',
                               'load' => 'Loader',
                               'db'   => 'Database'
                );

        foreach($object as $key as $class) {
             return $this->$key = new $class;
        }

    }
}


Tako da sada mogu objektima da pristupam jedino ako nasledim klasu Application kao sto sada radim

Code:

class Log extends Application {
 
    public function __construct()
    {
         parent:: __construct(); // Nasledjujem APP konstruktor

         if ($this->get_status() == true) {
        
            // Configuration 
            $this->set_path($this->cfg->logPath);                       // Directory name <full path>
            $this->set_date_format($this->cfg->logDateFormat);     // Date format
            $this->set_extension($this->cfg->logExtension);            // Log file extension
            $this->set_mode($this->cfg->logMode);                     // Writig mode
            $this->set_prefix($this->cfg->logPrefix);                   // File name prefix example(log_2012-06-26)
        }
        
        Log::log_message('debug','Log class initialized');
    }
   
}


Ali to je samo moguce ako nasledim trenutnu klasu koja mi ucitava ostale klase kao jedan ogroman super objekat.

Nisam radio sa referencama (&) sta mislis o tome? ako bih napravio jedan base file koji bi ucitavao i instancirao sve sto je nephodno dali pomocu referenci mogu ovo da odradim? Meni te reference uopste nisu jasne kada se radi sa funkcijama i klasama, jedno sto kapiram rad sa promenjivama.
[ dakipro @ 10.03.2013. 18:10 ] @
Ovako na blic nisam siguran da vidim neki benefit (a vidim dosta ogranicenja i problema) zasto bas svaka klasa nasledjuje Application, al ok.
Ako mozes da ubacis cfg u application, onda ga svi ostali nasledjuju. A php valjda po "defaultu" objekte prosledjuje funkcijama kao reference, ako hoces da imas kopiju moras da uradis clone.

Sad iz znatizelje, gde si video taj pattern ili praksu da sve klase naslede jednu super klasu?
[ alfa-pro @ 10.03.2013. 19:26 ] @
MA nisam nigde video nago sam nesto eksperimentisao i iskren da budem meni se to uopste nesvidja da mi svaka klasa nasledjuje App.
Mislim da cu na kraju da se opredelim za statiku.
[ dakipro @ 10.03.2013. 19:48 ] @
I meni deluje kao prilicno los princip, skoro pa narusava sve za sta se OOP svet u php-u borio. Static pattern je ok, ali kao i svaki ima svoje prednosti i mane. Ja ga vidim kao idealni pattern za CNF koji si spomenuo malopre (bar ja obicno za config koristim static pattern) ali pre nego pocnes da koristis iskljucivo jedan pattern za sve zivo, prouci malo neke od popularnih i vec proverenih sablona/patterna, mozda vec ima resenja za to sto pokusavas da izvedes.

Kao i sve u programiranju, pokusavamo da ne izmislimo toplu vodu vec da resimo problem koji je ispred nas
[ alfa-pro @ 11.03.2013. 13:27 ] @
To si skroz upravi. Razumem ja sve to koristim singleton i factory jedino kada moram. Eo npr u ovoj aplikaciji koju radim jedina stavka koja je singleton je BaseController. Ok hvala na utrosenom vremenu.
[ vilyu @ 11.03.2013. 16:46 ] @
Singleton ili static CFG, isto s*anje, drugo pakovanje. Globalna promenljiva je globalna, ma kako je zvali.

Dakle, ako ti je lepse da koristis Singleton, sa privatnim konstruktorom poput: $cfg = CFG::getInstance(); echo $cfg->logPath; onda koristi Singleton. Ako ti je lepse da to bude CFG::get('log_path'), koristi static metod. Oba resenja su jednako dobra/losa.

A kad god stignes, izbegavaj globalne promenljive, kako god da ih zoves. Neka Dependency Injection bude s tobom. :)
[ alfa-pro @ 13.03.2013. 13:57 ] @
Ma ok je to samo za ucitavanje za Konfiguracionih podataka ($cfg). Ja sam hteo nesto da izmajmunisem da napravim metodu koja sve klase koje ja definisem uraditi jednim objektom. Tako nesto sam video pre neki dan na Codeigniter. Covek je uradio slicno mom primeru predhodnom, ucitao je sve klase kao jedan super objekat i sada te instace su mu dostupne u bilo kojoj klasi > metodi bez ikakve potrebe ponovnog instanciranja u bilo kojoj klasi. Mada static radi posao nemogu da se zalim, samo pokusavam da skontam taj princip.
[ dakipro @ 13.03.2013. 14:01 ] @
postavi link ka primeru ako ga jos imas, da vidimo kako je to uradio
[ alfa-pro @ 13.03.2013. 15:46 ] @
Nemam link, jedino ti preostaje da downloadujes CI i da pogledas njegov Controller i Base Controller. Odatle sam ja uzeo primer sto sam stavio gore
[ dakipro @ 13.03.2013. 18:47 ] @
Davno sam koristio CI, ali prilicno sam siguran da su tamo sve klase dostupne tako sto su pri inicijalizaciji CI kontrolera setovane istom kao property?
Znaci kad se inicializuje base kontroler, u loaderu se setuju sve setovane klase kao i neke defaultne. Tako da posle mozes da ih pozivas sa
$ci = get_instance();
$ci->db;
$ci->view;
$ci->....

Ako hoces da ovo imitiras, onda bi trebao da u tvojoj Application klasi uradis isto, prilikom inicializacije same klase setujes sve propertije i posle ih imas dostupne u svim klasama koje nasledjuju Application.
[ bantu @ 14.03.2013. 07:53 ] @
Evo ovako iz glave singleton pattern.
Code:

class FrontController {

private static $instance = null;

    public static function getInstanceance() {
     
        if (self::$instance === null) {
            self::$instance = new FrontController();
        }
        return self::$instance;
    }

    private function __construct() {

    }
}


Nakon ovoga bilo gdje dobijaš istu instancu pozivom:

Code:

$fc = FrontController::getInstance();
[ alfa-pro @ 14.03.2013. 16:21 ] @
@Buntu nije meni problem u Singletonu razumem ja to jako dobro, skontao sam ja odma da ci radi singleton.

@dakipro da upravu si on sve poziva pomocu $CI->get_instance();

Ali vidis kako on isto ucitava klase kroz foreach koji sam ja gore naveo, i onda su mu u svakom kotroleru dostupne instance tipa ovoga.

Code:
$this->load->view('lazzy-load');
$this->load->db->query('lazzy-query');


On sve to ucitava u Base Controller a posle nasledjuje i setuje ga u konstruktoru __patern() . A da nema ono initializovanje on nebi mogao da
radi $this->load->view vec bi morao da setuje property $load i da initializuje $view = new View();

Mislim zapetljano je skroz ali opet kazem lepo izgleda taj nacin programiranja.... Sve u svemu resio sam sa static
[ dakipro @ 14.03.2013. 20:15 ] @
Pa da, on ima $this->view zato sto u CI svi kontroleri nasledjuju BAse kontroler, isto kao i ti sto zelis da nasledis Aplication.
kao sto sam i u proslom postu napisao "Ako hoces da ovo imitiras, onda bi trebao da u tvojoj Application klasi uradis isto, prilikom inicializacije same klase setujes sve propertije i posle ih imas dostupne u svim klasama koje nasledjuju Application. " kao sto si i poceo sa tim foreachom
[ Nikola Poša @ 15.03.2013. 21:30 ] @
Ne znam da li je to možda već pomenuto u nekom odgovoru, ali mislim da se to što tebi treba postiže uvođenjem Service Container-a (dependency injection container). Preporučujem ti da progooglaš na tu temu, kako bi stekao uvid u to šta je uopšte Service Container i na koji način se on koristi. Service Container se inače zasniva na Dependency Injection konceptu, pa bi zapravo bilo dobro da se najpre pozabaviš proučavanjem tog aspekta.

Ja inače do sada nisam imao neku preteranu potrebu za korišćenjem Service Container-a, ali ako bi to bilo neophodno, moj favorit je Pimple. On spada u kategoriju tkz. micro-service container-a. Dosta je lagan, sastoji se od jedne jedine klase, a njegovo funkcionisanje se u velikoj meri oslanja na anonymous f-je (closures), tako da ga možeš koristiti samo u okviru PHP 5.3.

Naravno, kao i za mnoge druge stvari, i izbor Service Container-a zavisi od razmere projekta u kojeg želiš da ga integrišeš. Pimple će verovatno završavati posao u nekim manjim projektima, dok bi za veće trebalo razmisliti o rešenjima kao što je npr. Symfony-ev service container.

Evo par odličnih članaka na temu Dependency Injection dizajn pattern-a, sa PHP primerima, naravno , kako bi bolje razumeo celu tu priču:
http://www.slideshare.net/fabpot/dependency-injectionzendcon2010
http://fabien.potencier.org/ar...1/what-is-dependency-injection
http://phpmaster.com/managing-class-dependencies-1/
http://phpmaster.com/managing-class-dependencies-2/
[ dsivic @ 20.03.2013. 21:29 ] @
A da jednostavno počnes koristiti jedan od framework-a... nije loša ideja? :)