Can you get a calling class's variables?

I have a class Page that creates an instance of DB, which is named $db.

In the __construct() of Page, I create the new $db object and I pull a bunch of config data from a file.

Now the DB class has a method _connectToDB() which (attempts) to connect to the database.

Is there a way in the DB class to call the parent class's config array? I don't want to make global variables if I don't have to and I don't want to grab the config data twice.

Pseudo code might look something like this...

$dbUsername = get_calling_class_vars(configArray['dbUserName']);

Answers


I find that it's often easier to initialise all the "important" objects close to whatever variables they need to know. You could try it this way:

/* Code to get config variables here */
$DB = new DB($config);
/* You might want to delete the database password from $config here */
$Page = new Page($config, $DB);

Doing it this way means you can also do type-checking on the database object if you want to:

class Page {
    function __construct(array $config, DBClass $db) { }
}

Why not pass the config parameters to the connectToDb function or pass the config data to the constructor of the DB class.

And to directory answer the question: you don't know anything about the outside calling context in your current context.


See debug_backtrace() to get information about calling classes or objects.

Then see Reflection to get more information on the properties of a given class or object.

edit: But for what it's worth, I'd also recommend passing the specific parameters you need. Referencing the caller's data probably constitutes Content Coupling.


You can use static if you want to share variables without passing these:

class page{
    static $configArray = [];
    function doWhatever(){
        $db = new DB();
        $db->connectToDB();
    }
}
class DB{
    function connectToDB(){
        $dbUsername = page::$configArray['dbUserName'];
    }
}

In this case makes sense to have those data as static, because even if you have a multiple instances of the page class, the config parameters should always be the same.

Anyway I think that could be better to construct and keep the $configArray only in the DB class. If you want to call it from outside you can use the same static logic.


You can pass the child a reference to the parent. For example:

class Parent {
  function __construct() {
    $this->myChild = new Child($this);
  }
  public function doSomething() {}
}

class Child {
  function __construct(Parent $parent) {
    $parent->doSomething()
  }
}

You may find this odd, since you're still in the parent's constructor, and thus your parent object isn't fully constructed yet. But you can still use $this as a reference to yourself, even in the constructor. You just need to be careful that your child doesn't refer to things in the parent that haven't been initialized yet.


In general there is no easy way to do this. but as a general design issue i can see why your avoid global variables, but in the case of application wide configuration it is perfectly reasonable to have global access to the properties.

you can either make your config data global or just pass the needed properties to the db object initialization.


Need Your Help

How to show button ‘Done’ on number pad on iPhone OS 4?

iphone uitextview uikeyboard ios4

I'd like to add a Done button to the iPhone number pad keyboard. There's even a handy space at the bottom left for just such a button.

Efficient Way To Query Nested Data

c# .net sql-server sql-server-2008

I have need to select a number of 'master' rows from a table, also returning for each result a number of detail rows from another table. What is a good way of achieving this without multiple querie...