PHP Register Class

Pagina: 1
Acties:

Onderwerpen


Verwijderd

Topicstarter
Hallo,

Ik was bezig met een Registerklasse op mijn mvc uit te breiden.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
class cRegistry 
{
    function load() 
    {
        $cDatabase = cDatabase :: get();
        if( !$cDatabase )
        {
            return false;
        }
        
        $rQuery = $cDatabase->prepare
        (
            "
            SELECT 
                *
            FROM 
                tblsettings
            "
        );
        
        if( $rQuery->execute() )
        {
            while( $aArray = $rQuery->fetch() )
            {
                $sVar = $aArray['key']."_".$aArray['name'];
                $this->$sVar = $aArray['value'];
            }
        }
    }
    
    public function __get( $sVar )
    {
        if( isset( $this->$sVar ) )
        {
            return $this->$sVar;
        }
        
        return false;
    }
}
?>



Deze werkt zoals die moet werken
code:
1
2
$cRegistry->load();
echo $cRegistry->key_naam;


Maar ik zou de informatie graag willen oproep via deze manier:
code:
1
echo $cRegistry->key->naam;


Dit houd in dat je voor elke key een eige klasse moet maken maar hoe maak je een class in een var?

Alvast bedankt

Chris

  • mithras
  • Registratie: Maart 2003
  • Niet online
Wat is key en wat is naam? Ik neem aan dat je key geïdentificeerd wordt mbv een naam?

Waarom sowieso de VB naamgeving cRegistry ipv Registry en Engels en Nederlands door elkaar gebruikken?

Verwijderd

Sowieso gebruik je nu "variabele variabelen" in jouw object. Dat zou ik niet doen. Sla de waarden gewoon op in een array die een property is van het object.

Verder heb je geen goede reden gegeven waarom je dat wilt. Welk "grand design" zit hierachter?

Overigens, je kunt natuurlijk gewoon $this->variabele = new Klassenaam() doen natuurlijk. Ik zie er alleen het voordeel niet van.

Verwijderd

Wat je kunt doen is je registry een object laten terug geven in de __get methode. Dit object krijgt bij de initiatie de waarde van 'key' mee.
Vervolgens maak je een __get methode in dit object die de eerder meegegeven key en de opgevraagde naam combineert.

Verwijderd

Topicstarter
mithras schreef op donderdag 31 december 2009 @ 17:44:
Wat is key en wat is naam? Ik neem aan dat je key geïdentificeerd wordt mbv een naam?

Waarom sowieso de VB naamgeving cRegistry ipv Registry en Engels en Nederlands door elkaar gebruikken?
Is een foutje ...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class cRegistry 
{
    function __construct() 
    {
        
        $cDatabase = cDatabase :: get();
        if( !$cDatabase )
        {
            return false;
        }
        
        $rQuery = $cDatabase->prepare
        (
            "
            SELECT 
                *
            FROM 
                tblsettings
            "
        );
        
        if( $rQuery->execute() )
        {
            $aObject = array();
            while( $aArray = $rQuery->fetch() )
            {
                $aObject[ $aArray['key'] ][ $aArray['name'] ] = $aArray['value'];
            }
            foreach( $aObject AS $iKey => $aArray )
            {
                $this->$iKey = (object) $aArray;
            }
        }
    }
}


Ik heb hem al, het was makkelijker dan verwacht. Misschien niet helemaal netjes but it works _/-\o_

Verwijderd

Nog steeds variabele properties :N

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

En dat terwijl het zo simpel is om gewoon je classes te laten inheriten van een generieke class waar je vervolgens prima properties van aan kan roepen. :o

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Verwijderd

Zou je er ook niet een Singleton van maken? (Weet niet helemaal waar je het allemaal voor gaat gebruiken maar ik kan me voorstellen dat het niet wenselijk is dat er meerdere instances van een registry gemaakt kunnen worden...)

[ Voor 68% gewijzigd door Verwijderd op 31-12-2009 18:57 ]


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Volgens mij gebruikt TS uberhaupt een verkeerd pattern / methode om te bewerkstelligen wat hij wil. Zoals ik nu kan zien, is dit niet een echt registry, maar meet een manier om settings/preferences op te slaan in een databasetabel.
Dus je hebt van een db (key) een host (naam), username (naam) en password (naam). Je hebt van categorie X een variabele Y met waarde Z. En TS noemt X een key, Y een naam en Z de waarde die hij terug wilt zien. Imho is dit dan niet de juiste manier om het op te slaan.

Daarnaast zie ik een registry meer als een grote vergaarbak waar je tijdens je application scope allerlei zaken in kan stoppen en er een naam aan kan geven. Dat is juist niet beperkt tot strings! Een registry is imho heel simpel iets als dit (geen singleton!):
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Registry{
  protected static $_store = array();

  public static function set ($name, $value) {
    $this->_store[$name] = $value;
  }

  public static function get ($name) {
    if (isset($this->_strore[$name])) {
      return $this->_store[$name];
    }
  }
}

Acties:
  • 0 Henk 'm!

Verwijderd

Ik zie persoonlijk tussen uw code en een singleton class niet echt een verschil. Door het gebruik van static methods en properties zit je ook altijd in dezelfde scope.

Een kleine verbetering van je code, een static var kunt je niet aanroepen met $this wel via self::

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Registry{
  protected static $_store = array();

  public static function set ($name, $value) {
    self::_store[$name] = $value;
  }

  public static function get ($name) {
    if (isset(self::_strore[$name])) {
      return  self::_store[$name];
    }
  }
}

Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 13-09 20:30

kokx

WIN

@cyf3r: Ook jij doet het fout, static variabelen roep je aan met self::$ (dus self::$_store moet het zijn in dit geval).

Echter, ik vind zelf (vooral in MVC) een registry niet zo'n heel handig idee. Een registry is puur bedoeld als een opslagplaats van allerlei objecten. En dat laat dan niet iets toe als lazy loading, en het verkleint ook de mogelijkheden om de configuratie te wijzigen. Of om bijvoorbeeld een Mock object te implementeren voor eventuele testsituaties.

Wat een heel stuk beter is, is het gebruiken van een Dependency Injection container. Dit laat lazy initialization van objecten toe, en dit laat ook meteen de juiste configuratie.

Meer leesvoer over Dependency Injection:
http://fabien.potencier.o...t-is-dependency-injection

[ Voor 14% gewijzigd door kokx op 03-01-2010 03:53 ]


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Verwijderd schreef op zondag 03 januari 2010 @ 00:07:
[...]


Ik zie persoonlijk tussen uw code en een singleton class niet echt een verschil. Door het gebruik van static methods en properties zit je ook altijd in dezelfde scope.
Wanneer je gaat testen (Phpunit bijvoorbeeld) schijnen singletons een pain in the ass te zijn. Statis methods zijn dan ook niet het beste, maar (schijnbaar) wel beter.
Een kleine verbetering van je code, een static var kunt je niet aanroepen met $this wel via self::
Dat was inderdaad dom. Maar het ging mij om het principe :)
offtopic:
En inderdaad self:$_store, ipv $this->_store of self::_store
kokx schreef op zondag 03 januari 2010 @ 03:52:
Echter, ik vind zelf (vooral in MVC) een registry niet zo'n heel handig idee. Een registry is puur bedoeld als een opslagplaats van allerlei objecten. En dat laat dan niet iets toe als lazy loading, en het verkleint ook de mogelijkheden om de configuratie te wijzigen. Of om bijvoorbeeld een Mock object te implementeren voor eventuele testsituaties.
Hoewel je gelijk hebt, is het nog steeds heel goed mogelijk (en handig) context aware componenten te maken. Ik ben heel erg beïnvloed door het Zend Framework, maar daar heb je bepaalde dingen die je in een registry kan plaatsen waardoor andere componenten daar gebruik van kunnen maken.

Bijvoorbeeld Zend_Translate. Als je een Zend_Translate object in het registry plaatst onder de naam Zend_Translate, worden automatisch labels van navigatieobjecten vertaald (menu's, sitemaps, breadcrumbs etc). Ook bij een formulier worden labels en descriptions automatisch vertaald. Dat geeft een ineens een heleboel extra functionaliteit aan je applicatie.
Wat een heel stuk beter is, is het gebruiken van een Dependency Injection container. Dit laat lazy initialization van objecten toe, en dit laat ook meteen de juiste configuratie.

Meer leesvoer over Dependency Injection:
http://fabien.potencier.o...t-is-dependency-injection
Natuurlijk is DI heel erg handig, maar als je verder toespitst op een DI container met php zie je dat het toch wel overkill is. Keith Pope heeft lange tijd een DI container in ZF proberen te integreren, maar is toch tot de conclusie gekomen dat het allemaal niet echt nodig is (http://www.thepopeisdead....nts/dependency_injection/).

Acties:
  • 0 Henk 'm!

  • kokx
  • Registratie: Augustus 2006
  • Laatst online: 13-09 20:30

kokx

WIN

@mithras: Hehe, ik ben inderdaad ook nog wat betrokken geweest bij die DI container in ZF, maar zelf zit ik tegenwoordig te denken dat de opzet voor een deel verkeerd is geweest. Zelf werk ik daarom met een eigen DI container, die meer 'gehardcode' is, in plaats van de erg dynamische container van het Zend_Di proposal.

En het registry is ook iets waar ik door ZF toch goed mee kan werken, hoewel ik dat voor veel componenten niet (meer) gebruik. Ik ben ook vooral mijn eigen container gaan gebruiken door de lazy injection.

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
offtopic:
Nu pas koppel ik je nickname aan je IRC nickname (die verschillen niet echt he ;)). Maar ik zit er af en toe onder JurianS #zftalk #zfalk.dev en #zym :)
Pagina: 1