Q:

Calling to a member function on a non-object Error

i'm having a trouble at the moment that i'm trying to access from a method of Wolf class to other method of Dog class. That's the code:
index.php
    require_once 'Wolf.php';
    require_once 'Dog.php';

    class StackOverflowExample{
        public static function run(){
            $dog = new Dog("Cokey");
            $wolf = new Wolf("Wolfenstein");

            $wolf->hunt();
        }
    }
    StackOverflowExample::run();

Wolf.php
class Wolf {

    private $_name;

    public function __construct($name){
        $this->_name = $name;
    }

    public function hunt(){
        return $dog->setLife(0);
    }

}

Dog.php
class Dog {
    private $_name;
    private $_life= 100;

    public function __construct($name){
        $this->_name = $name;
    }

    public function setLife($life){
        $this->_life = $life;
    }

    public function getLife(){
        return $this->_life;
    }
}

It gives me the next errors:
· Undefined variable: dog
· Call to a member function setLife() on a non-object
I have spent two days searching and I still having no way to fix.
Thanks you and sorry for my bad english.

A:

What you should do is to pass $dog around, in the hunt method, like this:
public function hunt(Dog $dog){
    return $dog->setLife(0);
}

You get the ability to validate that the dog variable is an instance of the expected class.
This method of passing objects around is called dependency injection.
If you want to pass around all sorts of animals you need to use another concept called inheritance:
abstract class Animal
{
    public $_life;

    public function setLife($life){
        $this->_life = $life;
    }

    public function getLife(){
        return $this->_life;
    }

}

class Dog extends Animal
{
    private $_name;

    public function __construct($name){
        $this->_name = $name;
    }
}

class Wolf {

    private $_name;

    public function __construct($name){
        $this->_name = $name;
    }

    public function hunt(Animal $animal){
        return $animal->setLife(0);
    }

}

Notice that the common methods and variables live in the parent class, and that you can create as many types as animals as you want.
If you follow this example you should find a way to declare the animal's name variable in the Animal class so you don't have to redefine it in all subclasses ;)

