Jump to content


Photo

problem with $this using multiple classes? *SOLVED*


  • Please log in to reply
23 replies to this topic

#1 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 02:11 AM

I have two classes, site and security, both defined in seperate files. I have a function in the security class that has to call the site class. The problem is that when I try to use the $this variable in the site function that I called, it thinks that this is an object of the security class, not of the site class.


Can anyone tell me why this is happening?

#2 toplay

toplay
  • Staff Alumni
  • Advanced Member
  • 973 posts

Posted 15 May 2006 - 02:26 AM

You have to create an instance of the site class before calling it within the security class. Unless the method that you're calling within the site class doesn't use $this, then you can call it from within the security class like so:

site::method_name();


hth.



#3 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 02:48 AM

[!--quoteo(post=373882:date=May 14 2006, 10:26 PM:name=toplay)--][div class=\'quotetop\']QUOTE(toplay @ May 14 2006, 10:26 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]
You have to create an instance of the site class before calling it within the security class. Unless the method that you're calling within the site class doesn't use $this, then you can call it from within the security class like so:

site::method_name();
hth.
[/quote]

I don't think you understood my problem, here it is in a diluted form:

securityclass.php:
class securityclass {

       function getuser() {
             global $site;
             $site->query({sql statement});
       }

}
$security = new securityclass;
siteclass.php
class siteclass {
          function otherfunction() {
          }
      function query($sqltext) {
               $this->otherfunction();
      }

}

That $this right here ^ doesn't work because it thinks it refers to the security class, not the site class. It says function not defined because otherfunction is in the site class, not the security class.

#4 trq

trq
  • Staff Alumni
  • Advanced Member
  • 31,041 posts

Posted 15 May 2006 - 02:57 AM

[!--quoteo--][div class=\'quotetop\']QUOTE[/div][div class=\'quotemain\'][!--quotec--]That $this right here ^ doesn't work because it thinks it refers to the security class[/quote]
How does it? There is no sign of inheritence and you dont define securityclass() within site class at all.

Im afraid, with the code you have posted, these classes are not related AT ALL. Well, not properly anyway. Global vars are bad, especially within classes.

What exactly are you trying to have happen? Can we see the client code your using to get this error?

#5 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 03:06 AM

Here's full text of securityclass.php:
class securityclass {
    
    function setuser($username) {
        $this->username = $username;
        $this->setcodes();
    }
    
    function getuserid() {
        global $tbl_users,$site;
        $obj_userid = $site->query("SELECT id FROM ".$tbl_users." WHERE username='".$this->username."'",__FILE__,__LINE__);
        $obj_userid = $site->fetch($obj_userid,'object');
        return $obj_userid->id;
        
    }
    
    function getcodeids($int_userid) {
        global $tbl_usersecuritycodes,$site;
        $obj_codeids = $site->query("SELECT codeid FROM ".$tbl_usersecuritycodes." WHERE userid='".$int_userid."'",__FILE__,__LINE__);
        $arr_codeids = $site->extractids($obj_codeids);
        return $arr_codeids;
    }
    
    function getcodes($arr_codeids) {
        global $tbl_securitycodes,$site;
        $obj_codes = $site->query("SELECT code FROM ".$tbl_securitycodes." WHERE codeIN IN (".explode(",",$arr_codeids).")");
        $arr_codes = $site->extractids($obj_codes);
        return $arr_codes;
    }
    
    
    function setcodes() {
        $userid = $this->getuserid();
        $codeids = $this->getcodeids($userid);
        $codes = $this->getcodes($userid);
        foreach ($codes AS $value) {
            $this->security[$value] = TRUE;
        }
    }
    
    function checkcode($code) {
        if (isset($this->security['SYSTEMADMIN'])) {
            if ($this->security['SYSTEMADMIN']) {
                return TRUE;
            } else {
                return FALSE;
            }
        } elseif (isset($this->security[$code])) {
            if ($this->security[$code]) {
                return TRUE;
            } else {
                return FALSE;
            }
        } else {
            return FALSE;
        }
    }
}

$security = new securityclass;
?>

Here's part of siteclass.php (only the functions called)
<?php

class siteclass {
var $lastsql = "";
var $insertid = 0;
var $testmode = TRUE;

    
    function query($sqltext,$file=0,$line=0) {
        print_r(get_class_methods($this));
        echo($sqltext);
        if ($file==0 && $line==0) {
            $this->reporterror('STANDARDS',Array($sqltext));
        }        
        if ($obj = mysql_query($sqltext)) {
            $this->lastsql = $sqltext;
            if (substr($sqltext,0,6)=="INSERT") {
                $this->insertid = mysql_insert_id();
            }
            return $obj;
        } else {
            $this->reporterror('MYSQL',Array($sqltext,'site->query')); // DIES RIGHT HERE
            return FALSE;
        }
    }
    
        
    function reporterror($type,$data) {
        switch ($type) {
            case 'MYSQL' :
            case 'TECHNICAL' : 
            case 'STANDARDS' : 
            default : 
                if ($this->testmode) {
                    echo $type."<BR>";
                    foreach ($data AS $value) {
                        print_r($value);
                    }
                }
            break;
        }        
    }

}
$site = new siteclass();
?>


I have no problem calling the class using siteclass::function() coding, I switched it thinking it would work better, and it didn't. Either way, site still thinks that $this is calling a securityclass object, not a siteclass object.

#6 emehrkay

emehrkay
  • Staff Alumni
  • Advanced Member
  • 1,214 posts

Posted 15 May 2006 - 04:11 AM

class one{
public function  fone(){
}
}



//other file
include 'classone.php';
class two{
public function ftwo(){
one::fone();
}


#7 emehrkay

emehrkay
  • Staff Alumni
  • Advanced Member
  • 1,214 posts

Posted 15 May 2006 - 04:35 AM

your second class would have to extend the first in order to use $this->method_from_first_class

#8 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 02:40 PM

[!--quoteo(post=373910:date=May 15 2006, 12:35 AM:name=emehrkay)--][div class=\'quotetop\']QUOTE(emehrkay @ May 15 2006, 12:35 AM) View Post[/div][div class=\'quotemain\'][!--quotec--]
your second class would have to extend the first in order to use $this->method_from_first_class
[/quote]

What's up with that? I'm in the site class and I can't call a function of the site class using $this? So, I have to call all my class methods using siteclass::method(), even though I'm calling within the same class? That is really fouled up logic.

#9 macdumbpling

macdumbpling
  • Members
  • Pip
  • Newbie
  • 9 posts

Posted 15 May 2006 - 03:12 PM

in one file, you can include both classes, giving them references:
require_once('securityclass.php');
require_once('siteclass.php');

$sec = new securityclass;
$site = new siteclass;

$sec->GetCodeIds($userID);
$site->function($site->global_siteclass_variable);

HTH

Also. One suggestion. I always use ExampleFunction() or ExampleClass{} and $exampleVariable formatting in my scripts. It's not a requirement by any means, but it certainly makes reading scripts a bit easier. Personal preference, though [img src=\"style_emoticons/[#EMO_DIR#]/smile.gif\" style=\"vertical-align:middle\" emoid=\":smile:\" border=\"0\" alt=\"smile.gif\" /]

#10 trq

trq
  • Staff Alumni
  • Advanced Member
  • 31,041 posts

Posted 15 May 2006 - 03:29 PM

[!--quoteo--][div class=\'quotetop\']QUOTE[/div][div class=\'quotemain\'][!--quotec--]Personal preference, though[/quote]
Very much so.

#11 macdumbpling

macdumbpling
  • Members
  • Pip
  • Newbie
  • 9 posts

Posted 15 May 2006 - 03:46 PM

[!--quoteo(post=374029:date=May 15 2006, 03:29 PM:name=thorpe)--][div class=\'quotetop\']QUOTE(thorpe @ May 15 2006, 03:29 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]
Very much so.
[/quote]

Grr...

#12 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 03:52 PM

OK, I still don't have a good solution to my problem.

Anybody else want to ring in?



#13 macdumbpling

macdumbpling
  • Members
  • Pip
  • Newbie
  • 9 posts

Posted 15 May 2006 - 04:15 PM

Why didn't that work?

[!--quoteo(post=374037:date=May 15 2006, 03:52 PM:name=mb81)--][div class=\'quotetop\']QUOTE(mb81 @ May 15 2006, 03:52 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]
OK, I still don't have a good solution to my problem.

Anybody else want to ring in?
[/quote]

#14 trq

trq
  • Staff Alumni
  • Advanced Member
  • 31,041 posts

Posted 15 May 2006 - 04:36 PM

To be honest I still dont understand what your problem is exactly. Once again I ask you... can we see the client code that proves your error? Also, I still dont see any sign of inheritence in these classes.

Again I would suggest droping the global declarations and either instatiating the site class within the security class, or use inheritence.

#15 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 05:03 PM

[!--quoteo(post=374057:date=May 15 2006, 12:36 PM:name=thorpe)--][div class=\'quotetop\']QUOTE(thorpe @ May 15 2006, 12:36 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]
Again I would suggest droping the global declarations and either instatiating the site class within the security class, or use inheritence.
[/quote]

As far as proving the inheritance, I did a print_r() on the $this object and it display the variables that were currently assigned to the security class. I also displayed the methods and it was the same, it showed the methods of the security class, not the site class.

I like your idea of declaring the site class inside the security class, but will that also have the same variable values as the global $site class or are they consider two seperate objects? (for example, if I call $site->lastid in the security class, will it be the same value as the $site->id I call from the regular page?) If so, how do I do declare that?




[!--quoteo(post=374046:date=May 15 2006, 12:15 PM:name=macdumbpling)--][div class=\'quotetop\']QUOTE(macdumbpling @ May 15 2006, 12:15 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]
Why didn't that work?
[/quote]

It didn't work because you weren't calling the site class from inside the security class.


#16 toplay

toplay
  • Staff Alumni
  • Advanced Member
  • 973 posts

Posted 15 May 2006 - 08:08 PM

mb81, I believe that you're not understanding us. I gave you one solution in the first post here and so have others.

Please read up some more on PHP OOP so you can implement a design that works for you. Only you really know what you want and need. Don't rush into creating a design that's not going to be effective or won't work. Look into design patterns and it may help you pick an approach.

instance / instantiate / new object:
[a href=\"http://us2.php.net/manual/en/language.oop.php\" target=\"_blank\"]http://us2.php.net/manual/en/language.oop.php[/a]

extend / inheritance:
[a href=\"http://us2.php.net/manual/en/keyword.extends.php\" target=\"_blank\"]http://us2.php.net/manual/en/keyword.extends.php[/a]
[a href=\"http://us2.php.net/manual/en/keyword.parent.php\" target=\"_blank\"]http://us2.php.net/manual/en/keyword.parent.php[/a]

Scope Resolution Operator:
[a href=\"http://us2.php.net/manual/en/keyword.paamayim-nekudotayim.php\" target=\"_blank\"]http://us2.php.net/manual/en/keyword.paama...nekudotayim.php[/a]

Patterns (PHP5+ page):
[a href=\"http://us2.php.net/manual/sv/language.oop5.patterns.php\" target=\"_blank\"]http://us2.php.net/manual/sv/language.oop5.patterns.php[/a]

[a href=\"http://www.zend.com/php/design/patterns1.php\" target=\"_blank\"]http://www.zend.com/php/design/patterns1.php[/a]
[a href=\"http://www.devshed.com/c/a/PHP/Design-Patterns-in-PHP-Factory-Method-and-Abstract-Factory/\" target=\"_blank\"]http://www.devshed.com/c/a/PHP/Design-Patt...stract-Factory/[/a]
[a href=\"http://www.devarticles.com/c/a/PHP/Introduction-to-Design-Patterns-Using-PHP/\" target=\"_blank\"]http://www.devarticles.com/c/a/PHP/Introdu...erns-Using-PHP/[/a]
Book: [a href=\"http://www.phparch.com/shop_product.php?itemid=96\" target=\"_blank\"]http://www.phparch.com/shop_product.php?itemid=96[/a]


#17 ryanlwh

ryanlwh
  • Staff Alumni
  • Advanced Member
  • 511 posts

Posted 15 May 2006 - 08:10 PM

class securityclass {

       function getuser() {
             global $site;
             $site->query({sql statement});
       }

}
Are you sure the "global" here picks up anything outside of the class scope?
Please use EDIT * 100...
Please use
or [php] * 1000...

PLEASE READ THE POSTED SOLUTIONS CAREFULLY * 1000000...

#18 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 08:41 PM

[!--quoteo(post=374118:date=May 15 2006, 04:08 PM:name=toplay)--][div class=\'quotetop\']QUOTE(toplay @ May 15 2006, 04:08 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]

Patterns (PHP5+ page):
[a href=\"http://us2.php.net/manual/sv/language.oop5.patterns.php\" target=\"_blank\"]http://us2.php.net/manual/sv/language.oop5.patterns.php[/a]

[/quote]

This page answered my question. I have read a couple of other things, and here is what I have found:

toplay, actually your first post did not solve the problem because the ($this) reserved word is based on the last instantiate class, so if you use a scope resolution operator (::) to call the function, then the last instantiated class is the one you are calling from, not the one you are in. I still don't understand why declaring the global didn't work, but I don't really care at this point.

Then, there was a post to say not to use the global instance of the class, but didn't explain anything about the singleton method as described in the above link to be able to access the same instance of the class.

Then, the other post was calling the class from outside of the other class, which didn't help me either, because I was calling it from inside the other class.

Thanks for the help.

[!--quoteo(post=374119:date=May 15 2006, 04:10 PM:name=ryanlwh)--][div class=\'quotetop\']QUOTE(ryanlwh @ May 15 2006, 04:10 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]
class securityclass {

       function getuser() {
             global $site;
             $site->query({sql statement});
       }

}
Are you sure the "global" here picks up anything outside of the class scope?
[/quote]

Yes it does, it is the way I have done other sites without a problem.


#19 ryanlwh

ryanlwh
  • Staff Alumni
  • Advanced Member
  • 511 posts

Posted 15 May 2006 - 08:48 PM

[!--quoteo--][div class=\'quotetop\']QUOTE[/div][div class=\'quotemain\'][!--quotec--]Yes it does, it is the way I have done other sites without a problem. [/quote]

But have you actually INSTANTIANTED a site class for $site??

$site = new SiteClass; //do you have this??

class securityclass {

       function getuser() {
             global $site;
             $site->query({sql statement});
       }

}

If you do not instantiate the site class in the global scope, then $site is NULL, so it doesn't have the member function "query"
Please use EDIT * 100...
Please use
or [php] * 1000...

PLEASE READ THE POSTED SOLUTIONS CAREFULLY * 1000000...

#20 mb81

mb81
  • Members
  • PipPipPip
  • Advanced Member
  • 120 posts

Posted 15 May 2006 - 11:35 PM

[!--quoteo(post=374129:date=May 15 2006, 04:48 PM:name=ryanlwh)--][div class=\'quotetop\']QUOTE(ryanlwh @ May 15 2006, 04:48 PM) View Post[/div][div class=\'quotemain\'][!--quotec--]
But have you actually INSTANTIANTED a site class for $site??

$site = new SiteClass; //do you have this??

class securityclass {

       function getuser() {
             global $site;
             $site->query({sql statement});
       }

}

If you do not instantiate the site class in the global scope, then $site is NULL, so it doesn't have the member function "query"
[/quote]

Yes I have that. That wasn't the problem. I could get to the siteclass and until I fixed it, I just couldn't get the site class to recognize itself.





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users