Link to home
Start Free TrialLog in
Avatar of thepadders
thepadders

asked on

Know if we are inside an object

I have this class:

class someclass {

function dosomething() {

echo "Where we called by causesomething() or from outside the class?";

}

function causesomething() {
$this->dosomething();
}

}

I want to diferentiate inside the dosomething() function between:

$class->dosomething();
and
$class->causesomething();

ie I want to know inside the dosomething() function if we where called from within the class.

Needs to work on PHP4, can't just use a private status unfortunatly.


Avatar of Diablo84
Diablo84

There might be a better approach but the most efficient method that comes to mind is to use a flag, for example:

<?php
class someclass {

 function dosomething($flag=0) {
  if ($flag == 1) {
   echo 'called by causesomething()<br>';
  }
  else {
   echo 'called outside of the class<br>';
  }
 }
 
 function causesomething() {
  $this->dosomething(1);
 }
 
}

$class = new someclass();

$class->dosomething();
$class->causesomething();
?>

Diablo84
Avatar of thepadders

ASKER

I want to prevent the function being called from outside, so the flag dosen't really help so much.
Depending on the actual scenario you may be able to shuffle the logic, eg:

<?php
class someclass {

 function dosomething($flag=0) {
  if ($flag == 1) {
   echo 'called from within class';
  }
 }
 
 function causesomething() {
  $this->dosomething(1);
 }
 
}

$class = new someclass();

echo 'calling via: $class->dosomething(): ';
$class->dosomething();

echo '<br>calling via: $class->causesomething(): ';
$class->causesomething();
?>

I will stand back and see if anyone else has an idea now if a flag isn't going to work here.

Diablo84
I'm pretty sure a flag is the optimal solution in php4 as Diablo stated.
You could set and unset a GLOBAL variable or class variable inside the desired public method so you don't have to worry about parameters, but either way you're going to have to do a little bit of extra work to get around the OO limitations of php4.

I tend not worry about this and just place the desired usage(public, protected, or private) within comments above each class method, and then add them in when you are able to use php5.  
I am actually trying to make a license.php file here and want a private function that can't be accessed by the "outside" world, ie it will decode some encrypted data and I don't want that data directly accessable. I would prefere not to have to reuse the decode process in each function that needs to decode it.

I guess I thought there would be a function like is_inclass(). I know there is a way for example of telling if a function is called statically, I am surprised you can't tell if you where called from inside/outside the class.



SOLUTION
Avatar of jdpipe
jdpipe
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Wonderful _GeG_.
Seeing answers like that is really the primary reason I hang around here.
Yeah that's nice stuff, GeG

I know it wasn't exactly in the question but... is there also then a way to stop external code from snooping on the 'private variables' of someclass?

JP
JP, the only way i can think of is very un-OOP (no surprise with PHP4 ;) )

class someclass{
      function getX(){
            return $this->x();
      }
      
      function setX($y){
            $this->x($y);
      }
      
      function x($y=null){
            static $x;
              $callers=debug_backtrace();
              if (isset($callers[1]) && isset($callers[1]['class']) && $callers[1]['class']=='someclass'){
                  if ($y!==null) {
                      $x=$y;
                  }
              } else {
                  trigger_error('Please use setX() and getX()', E_USER_ERROR);
              }
            echo "$x\n";
            return $x;
      }
}

now you have 'hidden' $x (like a private variable) and can access it only with getter and setter classes. Use _only_ if you need php4 :(
Ok right. So it's the static variable trick there. You could therefore combine the 'setX($y)' stuff from above with your debug_backtrace stuff to have private setters etc. It would be very slow compared to standard object variables, but I guess it would work. Nice one!

JP
Wow, thats very interesting. Thank you everyone. It is a shame debug_backtrack is 4.3 not 4.2, i will have to see if I can raise the required version. Thanks!