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.


thepaddersAsked:
Who is Participating?
 
_GeG_Connect With a Mentor Commented:
if you can use php >= 4.3

class someclass{
    function iAmPrivate(){
        $callers=debug_backtrace();
        if (isset($callers[1]) && isset($callers[1]['class']) && $callers[1]['class']=='someclass'){
             // everything is good, i am called by a class method
            return true;
        } else {
            trigger_error('Unauthorized access', E_USER_ERROR);
        }
    }

    function iAmPublic(){
        $this->iAmPrivate();
    }
}

$c=new someclass();
$c->iAmPublic();  // returns true
$c->iAmPrivate(); // error
someclass::iAmPrivate; // error
0
 
Diablo84Commented:
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
0
 
thepaddersAuthor Commented:
I want to prevent the function being called from outside, so the flag dosen't really help so much.
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Diablo84Commented:
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
0
 
matt_mcswainCommented:
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.  
0
 
thepaddersAuthor Commented:
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.



0
 
jdpipeConnect With a Mentor Commented:
Here is a solution that might do what you're looking for. It's probably not optimal but it gives an example of how to store private data that can only be accessed from certain methods.

I must reiterate the PHP really isn't a good choice of language if you need data security of this type. Consider a language with more evolved private/protected object orientation.

Here is my idea:

<?php


       // Usage
      
      $L = new LicenseObject();
      $L->checkLicense('AAABBBCCC');
      
      if($L->checkLicense()){
            print("Your license is OK\n");
            
            // do protected stuff
      }

class LicenseObject{
   
    function LicenseObject(){
    }
   
    function setOrRetrievePrivateData($key,$data=NULL){
          static $storedkey;
          static $storeddata;
          
          if(is_null($data)){      
                if($key==$storedkey){
                      return $storeddata;
                }
                die("Invalid access to stored data");
          }else{
                if($data!="AAABBBCCC"){
                      die("Invalid license");
                }
                $storeddata=$data;
                $storedkey=$key;
                return true;
          }
    }
   
    function checkLicense($data=NULL){
          static $storedkey;
          
          if($data){
                // License data has been submitted, check it and store in private variable
                $storedkey=md5($data);
                if($this->setOrRetrievePrivateData($storedkey,$data)){
                      return true;
                }else{
                      return false;
                }
          }else{
                // License data has not been submitted, just check it
                if($this->setOrRetrievePrivateData($storedkey)){
                      return true;
                }else{
                      return false;
                }
          }
    }
}

?>
   
0
 
matt_mcswainCommented:
Wonderful _GeG_.
Seeing answers like that is really the primary reason I hang around here.
0
 
jdpipeCommented:
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
0
 
_GeG_Commented:
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 :(
0
 
jdpipeCommented:
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
0
 
thepaddersAuthor Commented:
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!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.