tags:

views:

226

answers:

2

In a nutshell: how do I access the methods of a class that is instantiated by a method of a different class?

There is a bit of code I am looking at right now that does the following (altering the code is not an option, btw. It isn't mine... I'm just decipher it):

A class has a method that instantiates a different class. It looks something like this:

// this file is named fooClassHere.php

class Foo{
    public $meh;

    function bar(){
        $something = new Baz;
        $this->meh = $something->getStuff();
    }
}

What I am trying to figure out is how to access the methods of this instantiated class Baz. Another page contains something like the following:

include 'bazClassHere.php';
include 'fooClassHere.php';

$a = new Foo;
$a->bar();

So shouldn't all of Baz be available now in some manner (and not just getStuff() which I assigned to $this->meh)? The Foo and Baz classes are included, the code instantiates Foo and then calls Foo's method bar() which in turn instantiates the Baz class. Obviously the following will display data returned by Baz's getStuff() method:

var_dump($a->meh);

But I'd like to access all of Baz's available methods without going through the intermediate step of manually assigning them like I did inside Foo's bar method:

$this->meh = $something->getStuff()

Maybe something like (but of course this doesn't work):

$a = new Foo;
$a->bar(); //instantiates Baz as $something $a->something->fromBaz(); //$something is an instance of Baz, yes? No?

I hope this makes sense and I didn't confuse the issue with my notes. Ack! >_<

+3  A: 

If altering the code is not an option, you're out of luck. To achieve what you want you do this:

class Foo {
    public $meh;
    public $something;

    function bar(){
        $this->something = new Baz;
        $this->meh = $this->something->getStuff();
    }
}

And then later on you can do:

$foo = new Foo;
$foo->something->myBazMethod();
Paolo Bergantino
So OP's $a->something->fromBaz() will work? I.e., his something and your baz are instances of Baz?
Chry Cheng
no, the OPs would not work because $something is just a local variable to the bar() method. he needs to make something a class variable and set it through $this so that he can then access the new Baz object outside the class through a Foo object.
Paolo Bergantino
Fantastic! I duplicated the actual code I am looking at (since I can't change the original but want to actually see this work), made the variable that was instantiating Baz into a class variable and it works as advertised. That helps me get the whole OOP thing straighter in my head. Thanks (go FSU).
gaoshan88
+1  A: 

You could use __call on your Foo class, look it up on php.net

Basically, __call gets called when you try to call a function that the class doesn't have. In there, you could pass the request to your inner object instead.

class a
{
    protected $b;

    public function __construct()
    {
        $this->b = new b();
    }

    public function meh()
    {
        return 'meh';
    }

    public function __call($func, $param)
    {
        return call_user_func_array(array($this->b, $func), $param);
    }
}

class b
{
    public function yo($something)
    {
        return $something;
    }
}

$a = new a();
echo $a->meh();
echo $a->yo('dude!');
Mario
Hey Mario, do you have an example of how you would do this? I've used __call to handle a nonexistent method being called but not to access a method that DOES exist but is part of a different object.
gaoshan88
Sure, look at my updated answer.
Mario