SitePoint Sponsor

User Tag List

Results 1 to 18 of 18
  1. #1
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Basic PHP Classes/Objects Help

    I'm new to object oriented programming in PHP, so excuse me if my problem is obvious and/or a stupid mistake!

    I've bought the book 'The PHP Anthology Volume 1', and I'm using this as a basis for my learning.

    In the book, Harry has a MySQL class, which I can successfully use to connect to my DB and query it. I'm trying to make a small links engine where someone can add/remove/update links in the DB.

    My current code looks like this:
    PHP Code:
    <?php

    require_once('includes/MySQL.php');

    class 
    links extends MySQL {
        var 
    $name;
        var 
    $url;
        var 
    $description;
        var 
    $db;
        
        function 
    links() {
            
    $this->name '';
            
    $this->url '';
            
    $this->description '';
            require_once(
    'includes/dbinfo.php');
            
    $db = &new MySQL($dbhost$dbuser$dbpass$dbname);
        }
        
        function 
    getlinks() {
            echo 
    "ss";
            
    $sql "SELECT * FROM links";
            
    $result parent::query($sql);
            
    //echo $result;
            
    return $result;
        }
        
        function 
    addlink($lname$lurl$ldescription) {
            
        }
    }

    $link = &new links;

    echo 
    $link->getlinks();

    ?>
    When I run it I get some errors:
    Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/joseph/websites/studentlife/waikato/includes/MySQL.php on line 111

    Warning: mysql_error(): supplied argument is not a valid MySQL-Link resource in /home/joseph/websites/studentlife/waikato/includes/MySQL.php on line 112

    Notice: Query failed: SQL: SELECT * FROM links in /home/joseph/websites/studentlife/waikato/includes/MySQL.php on line 113
    I figure that 'getlinks' isn't seeing the connection object to the DB.

    Obviously I don't understand quite properly how the classes are meant to interact with each other. Please note I don't want just a solution, I want to understand why a certain solution works, or why a certain way is the best way of doing it. So if you could help me on this that would be great and much appreciated.

  2. #2
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I forgot to mention, dbinfo.php contains the username, password variables etc.

    I tried this small change as well, but I'm still stumped.

    PHP Code:
    <?php

    require_once('includes/MySQL.php');

    class 
    links extends MySQL {
        var 
    $name;
        var 
    $url;
        var 
    $description;
        var 
    $db;
        
        function 
    links() {
            
    $this->name '';
            
    $this->url '';
            
    $this->description '';
            require_once(
    'includes/dbinfo.php');
            
    $this->db = &new MySQL($dbhost$dbuser$dbpass$dbname);
        }
        
        function 
    getlinks() {
            echo 
    "ss";
            
    $sql "SELECT * FROM links";
            
    $result parent::query($sql);
            
    //echo $result;
            
    return $result;
        }
        
        function 
    addlink($lname$lurl$ldescription) {
            
        }
    }

    $link = &new links;

    echo 
    $link->getlinks();

    ?>

  3. #3
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This code should work better.

    PHP Code:
    class LinksGateway  {
        var 
    $dbConn;    
        function 
    LinksGateway(&$dbConn) {
            
    $this->dbConn =& $dbConn;
        }    
        function &
    getlinks() {
            
    $sql "SELECT * FROM links";
            return 
    $this->dbConn->query($sql);
        }    
        function 
    addlink($lname$lurl$ldescription) {
            
    /*  */
        
    }
    }
    require_once(
    'includes/MySQL.php');
    require_once(
    'includes/dbinfo.php');
    $dbConn = &new MySQL($dbhost$dbuser$dbpass$dbname);
    $linkGateway = &new LinksGateway($dbConn);
    $links $linkGateway->getlinks();
    while (
    $row $links->fetch()) {
       
    print_r($row);
       echo 
    '<br/>';

    Links should not extend MySQL. The data connection object (MySQL) should be instanciated and then passed into the Links constructor.

  4. #4
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for your help. I do have a question though. Why, in the line below ("$this...") do you use the '&' ? I understand that the $dbConn variable is being passed by reference to the constructor function, by why use it the second time?

    PHP Code:
    ...
        function 
    LinksGateway(&$dbConn) {
            
    $this->dbConn =& $dbConn;
        }    
    ... 
    A couple of pages over in the book, and I found an example very similar to yours...

    Thanks,
    Joseph.

  5. #5
    SitePoint Member
    Join Date
    Nov 2004
    Location
    Grand Rapids
    Posts
    20
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    passing by reference

    The use of the & tells PHP to pass the object a reference to the variable (in this case the DB object) rather than copying it. This means that you have just one DB object in memory, rather than two, and so reduces overheads.

    In PHP5 you do not need the & as objects are passed by reference automatically.

    James.

  6. #6
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, I understand what a reference is. But it looks weird having the reference operator on the right hand side of the equals. The function already has a referenced version of $dbConn, why again? If if looked like this instead:

    PHP Code:
    ...
        function 
    LinksGateway(&$dbConn) {
            
    $this->dbConn $dbConn;
        }    
    ... 
    would we be creating another copy of dbConn? Why?

  7. #7
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Brenden's code is helpful, but that doesn't answer why your code didn't work in the first place.

    The most obvious thing to me is that the links class extends MySQL and yet it instantiates a MySQL object as a class variable.
    PHP Code:
    $this->db = &new MySQL($dbhost$dbuser$dbpass$dbname); 
    When you want to execute the query, you call parent::query().
    That's a call to $this (the links object) not $this->db (the MySQL object which is the valid link resource).
    Zealotry is contingent upon 100 posts and addiction 200?

  8. #8
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by joefish
    Yes, I understand what a reference is. But it looks weird having the reference operator on the right hand side of the equals. The function already has a referenced version of $dbConn, why again? If if looked like this instead:

    PHP Code:
    ...
        function 
    LinksGateway(&$dbConn) {
            
    $this->dbConn $dbConn;
        }    
    ... 
    would we be creating another copy of dbConn? Why?
    Yes, you would be creating another copy of dbConn because the operator "=" means that the the left operand gets set to the value of the expression on the right. The important word in that sentence was value, which is pretty much the same as copy. If you want a reference, which you do, you need to use the ampersand.

    Heres some links:
    http://www.php.net/manual/en/languag...assignment.php
    http://ca.php.net/manual/en/language...rences.whatare
    http://www.phppatterns.com/index.php...leview/23/1/2/
    Last edited by Brenden Vickery; Dec 1, 2004 at 15:40.

  9. #9
    Employed Again Viflux's Avatar
    Join Date
    May 2003
    Location
    London, On.
    Posts
    1,127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Correct me if I'm wrong, but if you're already passing in a reference, is it not true that you don't need to AGAIN copy the reference. As far as the inner workings of the method are concerned, $dbConn is JUST a reference. All it has is a reference to the value, not the value itself.

    I know other languages work like this, never came across it in PHP and can't test it since I'm running PHP5...

    Interesting...

  10. #10
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's why I'm confused about it. That and your use of double negatives Viflux

  11. #11
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hmm, now youve got me wondering. Ive been using php5 for a while but thats how I used to do things... maybe that was the cause of weird bugs I used to get . Ill get time later tonight and test it if no one else does.

  12. #12
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In php4:
    PHP Code:
      
      $foo 
    =& new Foo;
      
      function 
    foo(&$bar// pass by ref
      
    {
          
    $this->bar =& $bar// assign a ref
      
    }
      
      function &
    getBar() // return a ref
      
    {
         return 
    $this->bar;
      
         
    // OR:
         
    return new Bar;
      } 

  13. #13
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, the code itself that you provided Brenden does work, with and without the second ampersand. I don't know how to test whether or not PHP is making a copy.

    For the benefit of my understanding (and while we're on the subject of references) I started using a templating system called 'htmltmpl'. (Yes, there may be others that do far more out there, but this is simple and meets my needs). In it's documentation (http://htmltmpl.sourceforge.net/php.html) there's an example that looks like this:

    PHP Code:
    <?
    require('htmltmpl.php');

    # Compile or load already precompiled template.
    $manager = new TemplateManager();
    $template =& $manager->prepare("template.tmpl"); ### notice the '&' on this line
    $tproc = new TemplateProcessor();
    ...
    I would have done it like this:

    PHP Code:
    <?
    require('htmltmpl.php');

    # Compile or load already precompiled template.
    $manager = &new TemplateManager();
    $template $manager->prepare("template.tmpl");
    $tproc = &new TemplateProcessor();
    ...
    I'm not sure that these two different methods are achieving the same thing. (I understand that a variable is being created by the 'new' keyword, hence why we use an ampersand when using 'new').

    Further, the PHP Anthology book has an example that looks like this:
    PHP Code:
    <?php

    class Bar {
    }

    class 
    Foo {
        function &
    getBar() {
            return new 
    Bar();
        }
    }

    $foo = &new Foo();
    $bar = &$foo->getBar();
    Here again we see the ampersand on the right. However the book does talk about it's use in this situation, saying that this is commonly used when a method will return objects. In your code, the LinksGateway function isn't returning anything.

  14. #14
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by McGruff
    In php4:
    PHP Code:
      
      $foo 
    =& new Foo;
      
      function 
    foo(&$bar// pass by ref
      
    {
          
    $this->bar =& $bar// assign a ref
      
    }
      
      function &
    getBar() // return a ref
      
    {
         return 
    $this->bar;
      
         
    // OR:
         
    return new Bar;
      } 
    Thanks McGruff, you posted while I was typing up my last reply. But, why assign the reference when the variable has already been passed by reference?

  15. #15
    SitePoint Addict
    Join Date
    May 2003
    Location
    Calgary, Alberta, Canada
    Posts
    275
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I havent tested this but you do need the reference the second time. To quote the manual: http://www.php.net/manual/en/languag...ces.whatdo.php
    PHP references allow you to make two variables to refer to the same content. Meaning, when you do:

    <?php
    $a =& $b;
    ?>

    it means that $a and $b point to the same variable.

    Note: $a and $b are completely equal here, that's not $a is pointing to $b or vice versa, that's $a and $b pointing to the same place.

    Note: If array with references is copied, its values are not dereferenced. This is valid also for arrays passed by value to functions.

    The same syntax can be used with functions, that return references, and with new operator (in PHP 4.0.4 and later):

    <?php
    $bar =& new fooclass();
    $foo =& find_var($bar);
    ?>

    Note: Not using the & operator causes a copy of the object to be made. If you use $this in the class it will operate on the current instance of the class. The assignment without & will copy the instance (i.e. the object) and $this will operate on the copy, which is not always what is desired. Usually you want to have a single instance to work with, due to performance and memory consumption issues.
    So, just because $dbConn was passed by reference does not mean that it is a reference like other languages. If you dont assign by reference, even if the variable is a reference, a copy will be made.

  16. #16
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    New Zealand
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, thanks for that.

  17. #17
    Employed Again Viflux's Avatar
    Join Date
    May 2003
    Location
    London, On.
    Posts
    1,127
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ya, thanks for checking into it.

    And sorry for the double negatives.

  18. #18
    Resident Java Hater
    Join Date
    Jul 2004
    Location
    Gerodieville Central, UK
    Posts
    446
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If I were you, never trust book code to work in copy and paste form. many books don't have 100% tested code it seems. I was looking at some code snippets in the "Advanced PHP" book by Geroge What-its-face (can't remember) my boss brought. Scanning through some code in there, I could see some typos in the code. (Not to mention if it was copy and poste, that would be too easy wouldn't it :-P )


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
  •