PHP: is current function running inside an object?

Viewed 97

Is there any way in PHP to tell if a function is being run from inside or outside a particular class of object?

function getToDaChoppa() {
    if( "we're inside the Choppa object" ) {
        $foo = "We're inside";
    } else {
        $foo = "We're outside";
    }
    echo $foo;
}

class Choppa() {
    public function getStatus() {
        getToDaChoppa();
    }
}

Running:

getToDaChoppa();
( new Choppa )->getStatus();

should echo:

We're Outside

We're Inside

3 Answers

A function on it's own doesn't know, if it's called from an class or not and that for good reasons. If the function behaves different, that would lead to very unmaintainable code and hard debugging, etc.

If you need the calling function and maybe ask, if this function belongs to an class/get the instance, the only way to do this is debug_backtrace. But in general you really only should do this, for debug code (as the name tells you).

Normally you would just have two functions for each case, or pass an parameter, which stores the desired information.

You could always pass an instance of the class through on top of a default value, then evaluate on the return of a get_class().

function getToDaChoppa($that = false) {
    $class = $that ? get_class($that) : '';
    if($class == "Choppa") {
        $foo = "We're inside";
    } else {
        $foo = "We're outside";
    }
    echo $foo;
}

class Choppa {
    public function getStatus() {
        getToDaChoppa($this);
    }
}


getToDaChoppa(); // Would return "We're outside" 
( new Choppa )->getStatus(); // Would return "We're inside"

See https://ideone.com/WWg1Hl for a working example.

You might use debug_backtrace(), go back one hop, and check if that was made from inside a class. I'm not sure I'd do this in production though...

function getToDaChoppa() {
    $bt = debug_backtrace();
    if (isset($bt[1]) && array_key_exists('class', $bt[1])) {
        echo "called from class\n";
    } else {
        echo "called directly\n";
    }
}

Clarification: if you want it to trigger only for one specific class:

function getToDaChoppa() {
    $bt = debug_backtrace();
    if (
        isset($bt[1]) &&
        array_key_exists('class', $bt[1]) &&
        $bt[1]['class'] === 'Choppa'
    ) {
        echo "called from class Choppa\n";
    } else {
        echo "called otherwise\n";
    }
}
Related