4

really simple one I'm guessing but why does the below not work? I'm guessing it's a scope thing where class2 isn't visible from within class1. Yes, I'm getting "Call to member function on a non-object" error.

class class1 {
    function func1() {
        $class2->func3();
    }
    function func2() {
        $this->func1();
    }
}

class class2 {
    function func3() {
        echo "hello!";
    }
}

$class1 = new class1();
$class2 = new class2();

$class1->func1;

If anyone can give me a fix for this I'd be very grateful. I've been searching around for a while but I'm getting lots of examples of others trying to instantiate new classes inside other classes and similar and not this particular problem I have.

You'd be right in thinking I don't do a whole lot with classes!

Lee Ward
  • 43
  • 1
  • 1
  • 4
  • $class1 and $class are Objects not Classes. Object is instance of some Class. You can have a lot of objects using the same class. – crash01 Sep 30 '12 at 16:40

4 Answers4

7

PHP does not bubblescope like JavaScript does, so your $class2 is undefined:

The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well […] Within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope.

Source: http://php.net/manual/en/language.variables.scope.php

In other words, there is only the global scope and function/method scope in PHP. So, either pass the $class2 instance into the method as a collaborator

class class1 
{
    function func1($class2) {
        $class2->func3();
    }
}

$class1 = new class1();
$class2 = new class2();
$class1->func1($class2);

or inject it via the constructor:

class class1 
{
    private $class2;        

    public function __construct(Class2 $class2)
    {
        $this->class2 = $class2;
    }

    function func1() 
    {
        $this->class2->func3();
    }
}

$class2 = new class2();
$class1 = new class1($class2);
$class1->func1();
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • 2
    This is excellent, I can actually reach the class I need to now so this is actually correct spot on so thanks for this! There is another problem I've got now but it'd be inappropriate to not do some research first before asking! Thanks again. – Lee Ward Sep 30 '12 at 17:34
2

I recommend you take a look at static functions/attributes. Basically you do not need to instantiate class2, you just have to define the function inside it as static. Take a look at the following implementation:

<?php
class class1 {
    function func1() {
        class2::func3();
    }
    function func2() {
        $this->func1();
    }
}

class class2 {
    public static function func3() {
        echo "hello!";
    }
}

$class1 = new class1();

$class1->func1();

?>

Its always nice to avoid instantiating objects as much as possible.

iNDicator
  • 534
  • 2
  • 6
  • 15
  • 1
    `"Its always nice to avoid instantiating objects as much as possible."` Why would that be then? – vascowhite Sep 30 '12 at 17:13
  • 1
    `Its always nice to avoid instantiating objects as much as possible.` - stick with imperative programming then, there's no point into advising not to use objects in OOP. – moonwave99 Sep 30 '12 at 17:32
  • In this particular example you don't even need to instantiate Class2, and you seem to be wrong if you believe static calls/attrs aren't OOP concepts! – iNDicator Sep 30 '12 at 21:27
0
class class1 {
    function func1() {
        //Initialize before using it.
        $class2 = new class2();
        $class2->func3();
    }
    function func2() {
        $this->func1();
    }
}

class class2 {
    function func3() {
        echo "hello!";
    }
}
jturolla
  • 6,596
  • 7
  • 26
  • 41
0

Two things:

Add brackets to the function call & use global to get the variable into scope

class class1 {
    function func1() {
        global $class2; // Get variable into scope
        $class2->func3();
    }
    function func2() {
        $this->func1();
    }
}

class class2 {
    function func3() {
        echo "hello!";
    }
}


$class1 = new class1();
$class2 = new class2();

$class1->func1(); // Add brackets for function call
zaf
  • 22,776
  • 12
  • 65
  • 95
  • 1
    while that would work, usage of the `global` keyword is strongly discouraged in OOP: http://stackoverflow.com/questions/5166087/php-global-in-functions/5166527#5166527 – Gordon Sep 30 '12 at 16:48