Search code examples
phpobjecttransferglobal

Transfer of an instanced object into a class


I was wondering what is the best way to transfer an instanced object into another class for local usage. I am also curious if this makes a differences with regards to memory usage.

I figured, there are mainly two ways:

1.) Transfer instanced objects via referencing to $GLOBALS:

class UserLogHandler {
  public function __construct() {
    $this->DB = $GLOBALS['DB'];
    $this->Security = $GLOBALS['Security'];
  }
  public function doSomeWork() {
    $this->DB->someMethod;
  }
}

or 2.) Transfer via handover:

class UserLogHandler($DB,$Security) {
    public function doSomeWork() {
        $DB->someMethod;
    }
}

It seems to me, that option 2 might be better suited for a complicated environment, although I find option 1 more appealing. Anyhow I would prefer a technical and/or logical explanation why to use one option over the other. If there is another, better option please let me know as well.

Thanks in advance and best wishes, Thomas


Solution

  • This is indeed a good question. I will say it depends upon your need. Lets analyze both your options one by one.

    Before starting, keep in mind that your object should always a complete object. It should not have a incomplete state. You can refer to this article for more understanding https://matthiasnoback.nl/2018/07/objects-should-be-constructed-in-one-go/

    1.) Transfer instanced objects via referencing to $GLOBALS:

    You must never use such methods as they are confusing. $GLOBALS lacks to tell you where and how a particular variable was created so You can't never be sure if this variable exist or what it holds. I will suggest you to use dependency injection for it

    use DB;
    use Security;
    
    class UserLogHandler
    {
        public function __construct(DB $DB, Security $Security)
        {
            $this->DB = $DB;
            $this->Security = $Security;
        }
    
        public function doSomeWork()
        {
            $this->DB->someMethod;
        }
    
    }
    

    See how you can now be sure that from where $DB and $Security where injected and what they hold. You can even enforce type of variable using type indication like Security $Security.

    This method comes handy when your class is heavy dependent on a particular variable. e.g. A model class will always need DB adapter or a PDF generator library will need PDF class essentially.

    2.) Transfer via handover

    This works as you expected but I think you made mistake while defining it. You need to write it like following.

    class UserLogHandler
    {
        public function doSomeWork($DB, $Security)
        {
            $DB->someMethod;
        }
    }
    

    This method comes handy when you need a particular variable in a particular function only. Example for it, will be like we need to get records from a model for some particular condition. So we can pass value in function and get results according to value.

    use DB;
    use Security;
    
    class UserLogHandler
    {
        public function __construct(DB $DB, $Security)
        {
            $this->DB = $DB;
            $this->Security = $Security;
        }
    
        public function doSomeWork($value)
        {
            if ($value = 'something') {
                $this->DB->someMethod;
            }
        }
    
    }
    

    As you can see that both methods can be used in conjugation. It only depends what is your requirement