SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Call to a member function on a non-object

    Hey.

    How can I use a variable throughout a class, when the variable is actually the instance of another class? For example, I have a class that goes like this:

    Code:
    require_once("a.inc.php");
    require_once("b.inc.php");
    require_once("c.inc.php");
    
    $a=new a;
    $b=new b("argument");
    $c=new c;
     
    class d {
    var $uid;
     
    function d() {
    $set=$a->getid(); //getid() is a function in the class 'a' that returns an array.
    						 //From that array we need to extract the value of 'uid'
    $this->uid=$set['uid'];
    }
    
    function getd() {
    
    $sql="SELECT d FROM data WHERE uid='$uid'"; 
    $c=$b->makequery("d",$sql); //makequery() is a function of the class 'b'
    return $c[0];
    }
    }
    But when I execute this code, I get the following error:
    Call to a member function on a non-object
    on the line:
    $set=$a->getid();
    Basically what I want is that the variables $a,$b, and $c that are instances of classes a,b, and c remain available throughout the new class d. Please tell me why I got that error and how to make those classes available throughout the new class without using a $a=new a in every function, and if you have any suggestions on how to optimize this code that would be helpful too

  2. #2
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You did not pass an "$a" into function d(). You either need to do function d(&$a) and pass $a into it, or do function d() { global $a; ... }
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  3. #3
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    are there any security concerns if using the global keyword with the variables?

  4. #4
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

  5. #5
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So what should I do? I can't use static variables since in some cases I'll need to change the values of some internal variables of the class. If I have a static variable defined as an instance of class a, can I use the functions of a all over the rest of the script? And can I use a function to change the value of an internal variable of $a? e.g

    Code:
    class a() {
    var $var;
    function change_var($val) {
    $this->var=$val;
    }
    }
    If I define a static variable as an instance of a, can I use the function change_var to change the value of $a->var?

    Please give me some suggestions on what I should do.

  6. #6
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I guess I am not clear on what you want to accomplish. It sounds like you want to have a function, that uses an object, and you want to be able to call that function from anywhere, but depending on where you are, you might want a different instance of the interal class?

    Sounds to me like a clear cut case you you should be passing the object into the function as a parameter, but I might not yet be understanding how your requirements.

  7. #7
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hi.
    let me state my requirements more clearly.

    I'm using a bunch of classes for things like querying the database, and some other internal tasks. These classes are used throughout the website, so if I need to change how a main operation works, I'll just have to change the code for that class and all of my scripts would be updated.

    Some of these classes need to query the database. So, in order to make things more maintainable, I'm trying to use the database class in other classes as well. Similarly, some classes require the other internal operations for which I want to use the classes I've written for that purpose. So what I want to do is, that at the beginning of each class, I declare the other classes it depends at, and those classes should be available in all of the functions of the class. E.g

    Code:
    <?
    require_once("a.inc.php");
    $a=new a;
    class d {
    //$a should be available as an instance of the class a in all of the functions
    //of the new class d
    }
    What is the best way to do that? Also, if you see any flaws in this method then please let me know since its best to change that right now when I'm in the beginning stages of writing the code.

  8. #8
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Probably the simplest thing to do is something like this:
    PHP Code:
    class {
      var 
    $conn;
      function 
    setDbConn(&$c) { $this->conn =& $c; }
      function 
    getData() {
        
    $result $this->conn->query('...'); 
        
    //...
      
    }

    and then make sure that you feed each instance of M you create with the database connection I needs via the
    PHP Code:
    $new_m_object =& new M;
    $new_m_object->setDbConn($appropriate_db_connection);
    echo 
    $m->getData(); 
    HTH

  9. #9
    FBI secret agent digitman's Avatar
    Join Date
    Sep 2004
    Location
    Work
    Posts
    697
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, but if I'm not mistaken I'll still have to add the:
    Code:
    $new_m_object =& new M; 
    $new_m_object->setDbConn($appropriate_db_connection);
    to every function in the class. Isn't there anyway that I only declare the instance at the beginning of the class, and access the class throughout each function of the class?

  10. #10
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by digitman
    to every function in the class. Isn't there anyway that I only declare the instance at the beginning of the class, and access the class throughout each function of the class?
    Yes, you have to tell every instance what database connection to use (you have to share the resource with the object, it can't come from nowhere), but from then on out, any funciton of the class can use $this->conn and have access to the database connection.
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  11. #11
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well as far as that is concerned, 3 in most case is the only one that applies in languages like PHP, and maybe 2 in cases where you are dealing with very large projects and you have lots of other poorly coded libraries.

    Anyhow, globals are not needed and it's easy to avoid them.

    ie. If you are happily coding along thinking, this is a "Process message, Run to Completion" system. **** is about to happen.

    Big time.
    That's a nice blunt way of putting it :-P

  12. #12
    SitePoint Enthusiast Refresh's Avatar
    Join Date
    Jul 2004
    Location
    Lausanne, Switzerland
    Posts
    46
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not really sure I understand what you want to do, but take this metaphor:
    You have a man in front of you (your d{} class) who's hungry, and you want to give him a pie (your a{} class ).
    The pie cannot appear out of nowhere, for him to eat it you should provide him with it... So "create" the pie, "create" the guy, and then $man->receivePie($myPie);

    OR, you can teach him how to bake one!

    class d{
    var $db;
    function d() {
    $this->db = db::connect('localhost', 'user', 'pass');
    $this->db->query('SHOW DATABASES');
    }
    }

    For the second solution you should research the "Template" class pattern I think.

  13. #13
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Of course, this means you have to give the keys to the pie store to every hungry object!!!.

    I would be inclined to give them the address of the PieFactory so they could do:
    PHP Code:
    $this->pie =& PieFactory::purchasePie('cherry'); 
    But you need to leave the option open to just feed the hungry object a $test_pie directly


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •