function call type???

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
PCSpectraRetired
Forum Newbie
Posts: 10
Joined: Sun Aug 28, 2005 7:55 pm

function call type???

Post 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 :)
User avatar
dbevfat
Forum Contributor
Posts: 126
Joined: Tue Jun 28, 2005 2:47 pm
Location: Ljubljana, Slovenia

Post 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?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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'] == '->');
}
PCSpectraRetired
Forum Newbie
Posts: 10
Joined: Sun Aug 28, 2005 7:55 pm

Post 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.
PCSpectraRetired
Forum Newbie
Posts: 10
Joined: Sun Aug 28, 2005 7:55 pm

Post 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 :)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post 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..
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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
PCSpectraRetired
Forum Newbie
Posts: 10
Joined: Sun Aug 28, 2005 7:55 pm

Post 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 :)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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...
Post Reply