Results 1 to 7 of 7

Thread: How to Restrict Object Instantiation to Other Classes?

  1. #1

    Thread Starter
    Hyperactive Member tomcatexodus's Avatar
    Join Date
    Feb 2001
    Posts
    372

    How to Restrict Object Instantiation to Other Classes?

    I'm looking for a way to restrict instantiation.

    If I have a class named Machine, and a class named Widget, how can I prevent the Widget class from being instantiated unless it is performed by a method in the Machine class?

    I know that nested classes are not valid, but this code exemplifies the functionality I'm looking to achieve:

    PHP Code:
    class Machine{

        private class 
    Widget{
            
    //Widget properties and methods
        
    }

        public function 
    makeWidget(){
            
    $newWidget = new Widget();
            return 
    $newWidget;
        }

        
    //Machine properties and methods

    }

    $myMachine = new Machine();
    $myWidget $myMachine->makeWidget(); //would work fine

    $myOtherWidget = new Widget(); //would fail 
    How can I achieve this?
    IWS

  2. #2
    PowerPoster
    Join Date
    Sep 2003
    Location
    Edmonton, AB, Canada
    Posts
    2,629

    Re: How to Restrict Object Instantiation to Other Classes?

    we can use the debug_backtrace() function to figure out which object called a class (if any), and so something like this should work for you:

    PHP Code:
    <?php
      
    class Widget {
        private 
    $_name;
        public function 
    __construct($name){
          
    $trace debug_backtrace();

          
    //make sure that an instance of Machine called us
          
    if(!isset($trace[1]) || (!$trace[1]['object'] instanceof Machine)){
            
    trigger_error("Widget class can only be instantiated from within the Machine class"E_USER_ERROR);
            
    //or throw an exception
          
    }else{
            
    $this->_name $name;
          }
        }
        public function 
    __toString(){
          return 
    $this->_name;
        }
      }
      class 
    Machine {
        public function 
    __construct(){ }
        public function 
    makeWidget(){
          
    $widget = new Widget("myNewWidget");
          return 
    $widget;
        }
      }
      
      echo 
    "make a new widget object from machine object:\n";
      
    $m = new Machine;
      echo 
    $m->makeWidget(); //will succeed and return the widget name
      
      
    echo "\n\n\n";
      
      echo 
    "make a new widget object:\n";
      echo new 
    Widget("someWidget"); //will cause a fatal error
    ?>
    this is probably not the ideal way of doing it (as other languages have a more direct way of finding out what the parent class is [parent not meaning inheritance here]), but I don't know of any other way for you to get what you want! it should give you the functionality that you're looking for.
    Last edited by kows; Apr 11th, 2010 at 09:09 AM.

  3. #3

    Thread Starter
    Hyperactive Member tomcatexodus's Avatar
    Join Date
    Feb 2001
    Posts
    372

    Re: How to Restrict Object Instantiation to Other Classes?

    Thanks Kows, seems that this is the best resolution. For questions like this, I use multiple forums, so for discussion's sake, here's what some other people had to say:

    http://forums.devshed.com/php-develo...es-693799.html

    http://forums.devnetwork.net/viewtopic.php?f=1&t=115183

    I'd mark this thread resolved, but I certainly want to see if any other viable options exist.
    Last edited by tomcatexodus; Apr 11th, 2010 at 10:50 AM.
    IWS

  4. #4
    PowerPoster
    Join Date
    Sep 2003
    Location
    Edmonton, AB, Canada
    Posts
    2,629

    Re: How to Restrict Object Instantiation to Other Classes?

    while I understand what that one person is saying when they mentioned that it "should be used for debugging," (assuming they were even talking about debug_backtrace) the function can serve purposes other than just debugging, too. and I don't think it's that messy.

    but I don't like the first solution that was offered, though the one that uses type hinting would be okay in some situations.

    as mentioned by the posts on those forums, PHP doesn't implement a perfect object model and doesn't "directly" support what you're trying to do. I'm not sure any other viable options do exist, but I'd personally like to see what penagate or visualAd have to say about this.

  5. #5

    Thread Starter
    Hyperactive Member tomcatexodus's Avatar
    Join Date
    Feb 2001
    Posts
    372

    Re: How to Restrict Object Instantiation to Other Classes?

    Quote Originally Posted by kows View Post
    as mentioned by the posts on those forums, PHP doesn't implement a perfect object model and doesn't "directly" support what you're trying to do.
    Unfortunately so, but I think the ends of your approach justifies it's means, in it mimics closely what I'm trying to achieve. Patiently awaiting nested classes.

    Quote Originally Posted by kows View Post
    I'm not sure any other viable options do exist, but I'd personally like to see what penagate or visualAd have to say about this.
    Agreed.
    IWS

  6. #6
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: How to Restrict Object Instantiation to Other Classes?

    I looked at this a few years ago. The debug_backtrace function was the only method I came up with back then also. Another method could be to share a token which is known only to the Machine and Widget classes but that requires some degree of physical separation between them and any "foreign" classes which oughtn't to be able to instantiate a Widget.

    Is this for a plugin system?

  7. #7

    Thread Starter
    Hyperactive Member tomcatexodus's Avatar
    Join Date
    Feb 2001
    Posts
    372

    Re: How to Restrict Object Instantiation to Other Classes?

    (Old post yes, but the question is still relevant)

    I'm not sure what you meant by plug in system, but it is for a component that can be used in an MVC framework, the Controller/View.

    After much searching, debug_backtrace() still holds the title, despite it's "messiness". Could you or anyone elaborate on how I'd implement a token as such? The Widget and Machine classes should not extend one another.

    As of the moment, this is the class hierarchy:

    PHP Code:
    abstract class Supervisor//aka Machine

        
    private static $isInitialized false;

        private static 
    $params = array(); //global properties

        
    public static function init($args){
            
    //set params and other stuff
            
    self::$isInitialized true;
        }

        public static function 
    makeAlpha($args){
            if(
    self::$isInitialized){
                return new 
    AlphaWidget($args);
            }
        }

    }

    abstract class 
    WidgetBase{

        
    //inheritable qualities
        
    public function makeBeta($args){
            return new 
    BetaWidget($args);
        }

        public function 
    makeGamma($args){
            return new 
    GammaWidget($args);
        }

        public function 
    makeDelta(...
        .
        .
        .

    }

    class 
    AlphaWidget extends WidetBase{

        
    //Alpha specific properties/methods

        
    public function __construct($args){
            
    //IF NOT CALLED FROM SUPERVISOR THROW EXCEPTION
            //do stuff
        
    }

    }

    class 
    BetaWidget extends WidgetBase{

        
    //Beta specific properties/methods

        
    protected function __construct($args){
            
    //do stuff
        
    }

    }

    class 
    GammaWidget extends WidgetBase{

        
    //Gamma specific properties/methods
        
    .
        .
        . 
    IWS

Posting Permissions

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



Click Here to Expand Forum to Full Width