Page 1 of 1

function call type???

Posted: Tue Sep 20, 2005 2:11 am
by PCSpectraRetired
This may not even be possible, but what the heck :)

Does anyone know of a way to determine whether a classes member function was called statically via the scope resolution operator :: or normally via ->

Is there anyway to determine this inside the function just called???

I hoping that PHP's powerful RTTI model supports such a thing...sure would be neat :) despite haveing another simple work-aorund...I think this approach would be much more elegant :)

Cheers :)

Posted: Tue Sep 20, 2005 6:54 am
by dbevfat
It can be read from the result of debug_backtrace(), but I wouldn't rely on it, since it's a debugging function and might change when you least expect it ...

Why do you need that?

Posted: Tue Sep 20, 2005 8:37 am
by feyd
we use these in our framework

Code: Select all

/**
 * isStaticCall
 * checks the call-stack to see if its calling method is being called statically
 * @param $aOffset integer how many more steps back into the call stack should it step
 * @author feyd
 * @return boolean
 */
function isStaticCall($Offset=0) {
  $stack = debug_backtrace();
  return (isset($stack[1+$Offset]) and isset($stack[1+$Offset]['type']) and $stack[1+$Offset]['type'] == '::');
}

/**
 * isStandardCall
 * checks the call-stack to see if its calling method is being called standardly
 * @param $aOffset integer how many more steps back into the call stack should it step
 * @author feyd
 * @return boolean
 */
function isStandardCall($Offset=0) {
  $stack = debug_backtrace();
  return (isset($stack[1+$Offset]) and isset($stack[1+$Offset]['type']) and $stack[1+$Offset]['type'] == '->');
}

Posted: Tue Sep 20, 2005 2:05 pm
by PCSpectraRetired
dbevfat wrote:It can be read from the result of debug_backtrace(), but I wouldn't rely on it, since it's a debugging function and might change when you least expect it ...

Why do you need that?
Cool... :)

Years of using PHP and i've never even known about these functions :)

However like you said, there is something about using a debug function in release code which leaves me feeling funny.

Posted: Tue Sep 20, 2005 2:17 pm
by PCSpectraRetired
feyd wrote:we use these in our framework

Code: Select all

/**
 * isStaticCall
 * checks the call-stack to see if its calling method is being called statically
 * @param $aOffset integer how many more steps back into the call stack should it step
 * @author feyd
 * @return boolean
 */
function isStaticCall($Offset=0) {
  $stack = debug_backtrace();
  return (isset($stack[1+$Offset]) and isset($stack[1+$Offset]['type']) and $stack[1+$Offset]['type'] == '::');
}

/**
 * isStandardCall
 * checks the call-stack to see if its calling method is being called standardly
 * @param $aOffset integer how many more steps back into the call stack should it step
 * @author feyd
 * @return boolean
 */
function isStandardCall($Offset=0) {
  $stack = debug_backtrace();
  return (isset($stack[1+$Offset]) and isset($stack[1+$Offset]['type']) and $stack[1+$Offset]['type'] == '->');
}
Interestingly enough...I need this functionality for a framework (of sorts) i'm working on as well :)

Anyways, like mentioned above...I feel queezy about using DEBUG functions inside production code, but I just thought of an possible alternative...

Inside the function could you not just do something like:

Code: Select all

if(is_object($this))
  // Called using the object via ->
else
  // Called statically via ::
See any downsides to this technique? Will this even work I wonder...or will PHP choke when is encounters $this inside a static function???

Cheers :)

Posted: Tue Sep 20, 2005 2:20 pm
by John Cartwright
One sloppy solution I see if setting a variable inside the constructor.. if the class was called normally set a variable, or not.. well do nothing.
When calling your class statically check to see whether that particular variable exists.

Doesn't seem very practical though..

Posted: Tue Sep 20, 2005 4:01 pm
by feyd
results from PHP 5.0.4

Code: Select all

[feyd@home]>php -r "class foo{ static function bar() { return is_object($this); } } var_export(foo::bar());"
PHP Notice:  Undefined variable: this in Command line code on line 1

Notice: Undefined variable: this in Command line code on line 1
false

Posted: Tue Sep 20, 2005 7:14 pm
by PCSpectraRetired
feyd wrote:results from PHP 5.0.4

Code: Select all

[feyd@home]>php -r "class foo{ static function bar() { return is_object($this); } } var_export(foo::bar());"
PHP Notice:  Undefined variable: this in Command line code on line 1

Notice: Undefined variable: this in Command line code on line 1
false
PHP 5 chokes eh....I kinda figured it would...I haven't tested it on 4 at all myself...so I dunno what would happen...but it's a scrap regardless cuz even if it did work on 4 it wouldn't be very portable code would it :)

Thanks :)

Posted: Tue Sep 20, 2005 7:26 pm
by feyd
works cleanly in PHP 5.0.4 and PHP 4.3.8

Code: Select all

[feyd@home]>php -r "class foo{ function bar() { return isset($this) && is_object($this); } } $boo = new foo(); var_export(foo::bar()); echo chr(13); var_export($boo->bar());"
false
true

however, this will only work at the current level of request.. the one I posted previously can see if any level of the call stack was either static or standard calling...