SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Zealot marcoBR's Avatar
    Join Date
    Jun 2002
    Location
    Brazil
    Posts
    149
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Classes available for others classes. Help!

    What's the most suitable design pattern to make all my classes available for others without instatiate it every time?! (php4)

    Assume I have a lot of classes: DB, Sections, Users, News, Templates, etc... For now Im instatiating classes in contructors ex:
    PHP Code:
    <?php
    class Users{

    function 
    Users(){
      
    $this->db =& new DB;
      
    $this->sections =& new Sections;
      
    $this->news =& new News;
      
    $this->Templates =& new Templates;
    }

    function 
    getUserById($id){
     
    // $this->db->query('blabla');
    }

    }

    class 
    Sections{

    function 
    Sections(){
      
    $this->db =& new DB;
      
    $this->users =& new Users;
      
    $this->news =& new News;
      
    $this->Templates =& new Templates;
    }

    function 
    getSectionById($id){
     
    // $this->db->query('blabla');
    }

    }
    ?>
    It's bad because it cause a loop... can you see it?!

    I think about call methods using the scope resolution operator '::', but how the most of my methods use DB calls I would like to know how to make DB availale for all those methods. Cause calling a method this way returns me an error cause DB object was not instantiate... Im in trouble. Please help me

    btw: sorry 4 my poor english. hope you can understand me...

  2. #2
    SitePoint Enthusiast
    Join Date
    Jul 2004
    Location
    NL, Rotterdam
    Posts
    38
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What I do is create an instance of a db. When creating instances of other classes I pass the db-object as reference.

    Code PHP:
    // sections class...
    class Sections
    {
      var $objDb;
     
      function Sections(& $objDb)
      {
        $this->objDb =& $objDb;
      }
    }
     
    // create objects
    $objDb = new Database();
    $objDb->configure($arrParam);
    $objDb->connect()
     
    $objSections = new Sections($objDb);

  3. #3
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Classic problem in dependency injection. A variety of solutions. Take a look at Jeff's slides from php|tek http://www.procata.com/blog/archives...phptek-slides/
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  4. #4
    SitePoint Evangelist
    Join Date
    Aug 2004
    Posts
    428
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question wheres my bad *** programmer avatar

    thanks for the slides... I like the driver solution.. remindes me of web.config and
    provider model in asp.net


    if you move towards in aggregation model instead of statically building the composite
    internally.. the problems discussed disappears.

    example: here would be my api


    $FeedCache = new MemoryCache(new FileSystemCache(...), ... , .. , ..);

    $FeedFetcher = new FeedFetcher( $FeedCache, $url );

    or

    $FeedFetcher = new FeedFetcher();
    $FeedFetcher->setCache( $FeedCache );




    ---------------------------

    anyways to answer the original posters question... seems like your solution
    needs more work. cyclic dependency is normally a problem with the approach taken.


    $user = new User($id);
    $user->Name('change name');
    $user->update();


    $user = new User();
    $user->Name('name');
    $user->create();

    in summary the user object shouldn't have all those composites... everytime you add a new section seems like you'll have to append your users object.. once you make the object you shouldn't have to update the object for a simple addition to the site.

    events (array of function pointers ) also allows decoupling... example
    if you $user->removePrivegele($sectionobject);
    your section object needs to be listening to update the appropriate views...
    you don't need composition as you'll be sending messages like these through events.


    your users object should only need
    $driver = 'userdatabase';
    this->db = DatabaseFactory::Create($driver); //look into singleton pattern

    all other "stuff" inside the user object is incorrectly placed.


    .... as for sections.
    its not a section so you shouldn't need it.
    and no section should need the user object.... they should only
    need authorization object which has the user object as a composite....
    the authorization object (un)serializes user object across page loads and tells you previlege info.

    if you're rendering sections differently for different users you need to move
    to a visitor renderer so that you don't need to update the section object for a change in html.

  5. #5
    SitePoint Zealot marcoBR's Avatar
    Join Date
    Jun 2002
    Location
    Brazil
    Posts
    149
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I found http://drip.tigris.org
    It seems to do exactly I want.
    What do you think about it?! Worth a try or maybe another simpler solution?!

  6. #6
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you read over Jeff's presentation, his conclusion was pretty much that PHP applications typically never evolve to the state of needing an IoC container, but by following general principles of dependency injection you can lead yourself to a better design for your code.
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  7. #7
    SitePoint Zealot marcoBR's Avatar
    Join Date
    Jun 2002
    Location
    Brazil
    Posts
    149
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I get some code from related threads in forum and impemented this:
    PHP Code:
    <?php

    class DI 

         
        
    #   Factory 
        
    function &nuovo $name 
        { 
            
    $di =& DI::_get_registry(); 
            if ( isset(
    $di['instances'][$name]) ) 
            { 
                return 
    $di['instances'][$name]; 
            } 
            else if ( 
    $di['signatures'][$name] ) 
            { 
                
    $signature $di['signatures'][$name]; 
                
    $arguments func_get_args(); 
                
    $dependancies = array(); 
                 
                foreach ( 
    $signature as $sig 
                { 
                    if ( 
    $sig $dependancies[] =& DI::nuovo($sig); 
                    else        
    $dependancies[] = next($arguments); 
                } 
                 
                
    $t =& call_constructor_array($name$dependancies); 
                return 
    $t
            } 
        } 
        
    ### 
         
        
    function instance $name, &$instance 
        { 
            
    $di =& DI::_get_registry(); 
            
    $di['instances'][$name] =& $instance
        } 
        
    ### 
         
        
    function register $name 
        { 
            
    $signature func_get_args(); array_shift($signature); 
            
    $di =& DI::_get_registry(); 
            
    $di['signatures'][$name] = $signature
        } 
        
    ### 
         
        
    function &_get_registry() { 
            static 
    $_DI_ = array(); 
            return 
    $_DI_
        } 



    function &
    call_constructor_array $type$array )
    {
        
    $params '';
        if(
    $count count($array))
        {
            
    $params '$array[' implode('], $array['range(0$count 1)) . ']';
        }
        eval(
    "\$temp =& new $type($params);");
        return 
    $temp;
    }


    class 
    A{

        function 
    set(){
            
    $this->=& DI::nuovo('B');
            
    $this->=& DI::nuovo('C');
            
    $this->=& DI::nuovo('D');
        }

        function 
    sayA(){
            echo 
    'from A<br>';
        }

        function 
    sayAB(){
            
    $this->set();
            echo 
    'say AB from A<br>';
            echo 
    $this->b->sayB();
            echo 
    $this->c->sayC();
            echo 
    $this->c->sayD();
        }
    }

    class 
    B{

        function 
    sayB(){
            echo 
    'from B<br>';
        }

        function 
    sayACD(){
            echo 
    'say ACD from B<br>';        
        }
    }

    class 
    C{

        function 
    set(){
            
    $this->=& DI::nuovo('D');
        }

        function 
    sayC(){
            
    $this->set();
            echo 
    'from C<br>';
        }

        function 
    sayD(){
            echo 
    $this->d->sayD();
        }
    }

    class 
    D{

        function 
    sayD(){
            echo 
    'from D<br>';
        }
    }

    $a =& new A;
    $b =& new B;
    $c =& new C;
    $d =& new D;

    $di =& new DI;
    $di->register('A');
    $di->instance('A'$a);
    $di->register('B');
    $di->instance('B'$b);
    $di->register('C');
    $di->instance('C'$c);
    $di->register('D');
    $di->instance('D'$d);

    $a->sayAB();

    ?>
    It seems to be working, but I really dont know how to use it properly. Any suggestions?!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •