?
Solved

Know if we are inside an object

Posted on 2005-05-10
12
Medium Priority
?
239 Views
Last Modified: 2010-05-18
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.


0
Comment
Question by:thepadders
  • 3
  • 3
  • 2
  • +2
12 Comments
 
LVL 27

Expert Comment

by:Diablo84
ID: 13974493
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
 

Author Comment

by:thepadders
ID: 13974546
I want to prevent the function being called from outside, so the flag dosen't really help so much.
0
 
LVL 27

Expert Comment

by:Diablo84
ID: 13974573
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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 11

Expert Comment

by:matt_mcswain
ID: 13974798
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
 

Author Comment

by:thepadders
ID: 13974817
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
 
LVL 7

Assisted Solution

by:jdpipe
jdpipe earned 400 total points
ID: 13975534
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
 
LVL 9

Accepted Solution

by:
_GeG_ earned 1600 total points
ID: 13975808
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
 
LVL 11

Expert Comment

by:matt_mcswain
ID: 13975901
Wonderful _GeG_.
Seeing answers like that is really the primary reason I hang around here.
0
 
LVL 7

Expert Comment

by:jdpipe
ID: 13975949
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
 
LVL 9

Expert Comment

by:_GeG_
ID: 13976068
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
 
LVL 7

Expert Comment

by:jdpipe
ID: 13976149
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
 

Author Comment

by:thepadders
ID: 13991457
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

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
There are times when I have encountered the need to decompress a response from a PHP request. This is how it's done, but you must have control of the request and you can set the Accept-Encoding header.
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses
Course of the Month15 days, 6 hours left to enroll

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question