2

I have been told that a class cannot be defined within a class in PHP. However, in my own example this seems to work which has me confused:

class_test.php:

require('class_1.php');
new class_1
//Need $missing_variable here.

class_1.php

class class_1{
    public function function_1(){
        function callback_function(){
            echo "A Callback";
            $missing_variable = "Where Did I Go?";
        }
        require('class_2.php');
        new class_2('callback_function');
    }
    public function __construct(){
        $this->function_1();
    }
}

class_2.php

class class_2{
    public function __construct($callback){
        echo "Hello World - ";
        call_user_func($callback);
    }
}

Loading class_test.php prints out

Hello World - A Callback

Question: How do I define $missing_variable such that I can get it where I need it?


In case anyone in the future has a similar problem, however unlikely that may be, I want to link to the codepad from below that shows the $missing_variable echo'd from outside the classes:

http://codepad.org/tRk0XWG7

Thanks again everyone.


Note: This is a follow up.

3
  • A function is requireing another class within a class... is this the source of your confusion? Commented Nov 20, 2012 at 11:13
  • Yes indeed..... but what is confusing me is it isn't just requiring another class, it is requiring another class that uses a function from itself as a callback in the second class..... I am confusing myself :( The code is there... Commented Nov 20, 2012 at 11:15
  • Turns out my major misunderstanding, among many, was that when you define a class or function it exists inside of that scope. Turns out it is conditional (only defined when the container is called) but still exists on its own and can be called from anywhere. Today I was gifted a much better understanding of OOP. Thank you everyone! I am choosing Kavi Siegel for the codepads here and deceze on the other question for the great explanation. Thanks again! Commented Nov 20, 2012 at 11:59

2 Answers 2

3

You can declare a class within a function. That's known as conditional declaration, i.e. only if the function is called will the class be declared. It doesn't make much of a difference then whether you include a file with the class declaration or if you type out the code inside the function.

This does not mean however that the classes share any sort of scope or data. Only the declaration is conditionally nested, it still has the same functionality and scope as explained before.

Your confusion about the callback can be explained by the same thing. When class_1::function_1 is executed the first time, the function callback_function is being defined. This is a regular global function that can be called from anywhere. It's not bound to the class in any way. You will also notice that you cannot execute class_1::function_1 a second time, PHP will complain that callback_function already exists when you're trying to declare it again.

As for the comment in the source code //How do I declare this variable so that it is available where I need it?: You don't. That variable is a local variable inside a function. It's only in scope inside the function. You can return its value from the function like any other return value if you want to. (You could make it global, but for the love of god don't!) If you need that value somewhere else, don't declare it as a variable inside a function, because only the function can access it then.

Sign up to request clarification or add additional context in comments.

8 Comments

AH! So the classes Don't share scope...... i.e. it would work the same as if it was declared seperately/prior... What about instantiation? If I instantiate the class within the function/first_class then that new class object exists in the scope of the first_class and further in the function right?
A class instance, i.e. object, is just a value. The variable that this object is assigned to is subject to the same rules as all other variables, as explained in my other answer. So you have a variable which is an object inside a function inside a class. Whoopdidoo, same as if you have that variable outside a function outside a class. :)
Smart A*s (for the record I upvoted the whoopdidoo too, lol).
@Sam If you want to make it a class property so it can be accessed by anything that has access to the class/object, by all means go ahead and do so. What you cannot do is reach into a function and grab random variables out of it, that is simply not possible.
@Sam Yes. I'd say the primary purpose of a function is to have reusable code snippets, but yes, separation of scope is an essential byproduct of that. If your entire application depends on a certain global variable name, you'll have a hell of a time keeping everything straight. Make the scope of variables as limited as possible, hand values back and forth by passing them through defined interfaces (function parameters, return values).
|
1

You would return $missing_variable in a few places. See below. (This isn't the only way to do it, mind you)

http://codepad.org/tf08Vgdx

<?
class class_2{
    public function __construct($callback){
        echo "Hello World - ";
        $missing = $callback();
        $this->missing = $missing;
    }
}
class class_1{
    public function function_1(){
        function callback_function(){
            echo "A Callback. ";
            $missing_variable = "Where Did I Go?";
            return $missing_variable;
        }
        $class2 = new class_2('callback_function');
        return $class2->missing;
    }
    public function __construct(){
        $this->missing = $this->function_1();
    }
}

$class = new class_1();

echo $class->missing;

5 Comments

I see...... if I require the second class within the first class (I need to nest them because I am requiring classes dynamically as I need them) then how do I get the variable outside of both classes? It is also important to note that the callback function exists inside of class_1 and is sent to class_2.
if a function (within a class or not) returns a value you can capture it outside the function (or class) in a variable: $variable = $class->missing; echo $variable; taken from the above code
I am sorry, I am sure you are explaining it wonderfully, but I am having a blonde moment here......... codepad.org/OCfrNSsv. ?!?
class_2 isn't defined in class_1, and class_1 isn't defined as a variable. See here: codepad.org/tRk0XWG7
Maybe this is my issue...... If I use the function user_callback_func as it is used in the code above.... does that function exist in the scope of class_1 or class_2? if I make it, say $this->output = user_callback_func($callback); Then, regardless that its in class_1, the return of the function will be passed in the scope of class_2, right? Thus, if class_2 is instantiated inside of class_1 I should be able to go echo $class_2->output from inside class_1, right?!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.