SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 51
  1. #1
    Non-Member coo_t2's Avatar
    Join Date
    Feb 2003
    Location
    Dog Street
    Posts
    1,819
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)

    keeping queries out of classes

    Do you think it's a good idea to send SQL statements through the constructor
    if you need to make any queries in the class?

    The way I figure it is if you construct the SQL statement in the class
    then that class is tied to that particular application and to that particular
    table structure. If you send the SQL statement in the constructor you can
    make it less dependent on the outside environment?

    But would sending the SQL statement to the class violate the principle of "encapsulation" in a situation such as the one below?

    I mean in some cases sending the SQL statement in the constructor means you have to know
    about the details of the implementation to some degree right?

    But on the other hand it seems like not constructing the SQL statement in the
    class would often result in a more reusable class.

    Below is part of a class I'm working on. I've only included the relevant parts.

    Would it make sense to supply the prepared sql statement in the constructor
    then just execute that query in loadBidderList() ?

    PHP Code:

    <?php

    class Auction {

        var 
    $dbObj;
        var 
    $auctionId;
        var 
    $bidders;

        function 
    Auction(&$dbObj$auctionId)
        {   
            
    $this->dbObj =& $dbObj;
            
    $this->auctionId $auctionId;

            
    $this->loadBiddersList();
        }



        function 
    loadBiddersList()
        {   

            
    $query 'SELECT * FROM auctionBidders '.
                     
    'WHERE auction_id=?' ;

            
    $MySqlStatementObj =& new MysqlStatement($query$this->dbObj->getLink());
            
    $MySqlStatementObj->setParameter(1$this->auctionId);
            
    $MySqlQueryResultObj =& $MySqlStatementObj->execute();

            
    $QueryIterator =& new QueryIterator($MySqlQueryResultObj2);

            while ( 
    $QueryIterator->isValid() )
            {   
    $bidders[] = $QueryIterator->getCurrent();
            }
            
        }
    }

    ?>

    Here's the relevant parts of the class using sql statement from the outside world:

    PHP Code:

    <?php


    $query 
    'SELECT * FROM auctionBidders '.
             
    'WHERE auction_id=?' ;

    $MySqlStatementObj =& new MysqlStatement($query$dbObj->getLink());
    $MySqlStatementObj->setParameter(1100);
    $MySqlStatementObj->prepare();
    $fixedQuery $MySqlStatementObj->getPreparedStatement();

    $auctionObj =& new Auction($dbObj100$fixedQuery);


    class 
    Auction {

        var 
    $dbObj;
        var 
    $auctionId;
        var 
    $bidders;
        var 
    $bidderListSql;

        function 
    Auction(&$dbObj$auctionId$bidderListSql)
        {   
            
    $this->dbObj =& $dbObj;
            
    $this->auctionId $auctionId;
            
    $this->bidderListSql $bidderListSql;

            
    $this->loadBiddersList();
        }



        function 
    loadBiddersList()
        {   

            
    $MySqlQueryResultObj =& $this->dbObj->query($this->bidderListSql);

            
    $QueryIterator =& new QueryIterator($MySqlQueryResultObj2);

            while ( 
    $QueryIterator->isValid() )
            {   
    $bidders[] = $QueryIterator->getCurrent();
            }
            
        }
    }

    ?>
    Actually this isn't a great example because one of the elements used in
    the sql statement is already passed in the constructor, because I want it
    as a member anyway.

    But the table name isn't supplied.

    Actually an idea just popped in my head. I'm sure it's not original but
    I don't think I've seen it done before.

    I could pass an object in the constructor that holds all the information needed
    to form an sql statement.

    Maybe something like:

    $queryStatementElements->getOrderByField();
    $queryStatementElements->getSelectFields();
    $queryStatementElements->getTables();
    $queryStatementElements->getWhereClause();

    etc..

    You see where I'm going with this?
    Then I could pass this in my constructors and do something like this
    in the recieving class:

    $query = "SELECT $queryStatementElements->getSelectFields() ".
    "FROM $queryStatementElements->getTables() ".
    "WHERE $queryStatementElements->getWhereClause() ".
    "ORDER BY $queryStatementElements->getOrderByField()";


    Passing an object like that would be better than passing each element wouldn't
    it?


    Anyways I think I'm starting to ramble so I'll cut this off.

    tia,
    --ed

  2. #2
    Non-Member coo_t2's Avatar
    Join Date
    Feb 2003
    Location
    Dog Street
    Posts
    1,819
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Another thing I guess I could do is to put my queries in abstract methods. Then I could just extend the class and supply the queries needed by defining the methods in the extended class.

    Simple example:

    PHP Code:
    class {
        var 
    $dbObj;
        function 
    A($dbObj)
        {   
    $query $this->getQuery1();
             
    $result $dbObj->query($query);
        }
       
        function 
    getQuery1()
        {   die(
    'Abstract method "getQuery" not defined');
        }
    }

    class 
    extends {
        
        function 
    getQuery1()
        {    return (
    'SELECT blah FROM blah_blah');
        }


    Heh?

    P.S. The code above and in the previous post isn't really meant to be
    runnable code. Right now I'm concerned mostly with theory.

    --ed

  3. #3
    SitePoint Zealot prefab's Avatar
    Join Date
    Jan 2003
    Location
    Belgium
    Posts
    133
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by coo_t2
    Another thing I guess I could do is to put my queries in abstract methods. Then I could just extend the class and supply the queries needed by defining the methods in the extended class.
    That's the way I like to implement similar classes that need to query the database. I like to have an object for (almost) every type of data/table I need to manipulate. I have a 'base' class I extend for specific needs, plus, I can always query the db directly through the class (my base class extends my database class) should I need to.

    -prefab

  4. #4
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sounds like you're ready for a Data Access Object (DAO). DAOs are great because you can keep all the SQL necessary for a domain model class isolated in a single DAO class. Generally speaking, you have one DAO class per database table.

    Here's some extensive example code for a hypothetical Bidder class that I adapted from my own class library/framework.

    Bidder.class.php:
    PHP Code:
    class Bidder
    {

        var 
    $email;
        var 
    $id;
        var 
    $name;
        
        function 
    Bidder($id$name$email)
        {
            
    $this->setId($id);
            
    $this->setName($name);
            
    $this->setEmail($desc);
        }
        
        function 
    getEmail()
        {
            return 
    $this->email;
        }
        
        function 
    getId()
        {
            return 
    $this->id;
        }
        
        function 
    getName()
        {
            return 
    $this->name;
        }
        
        function 
    setEmail($val)
        {
            
    $this->email $val;
        }
        
        function 
    setId($val)
        {
            
    $this->id $val;
        }

        function 
    setName($val)
        {
            
    $this->name =& $val;
        }
        

    BidderDao.class.php:
    PHP Code:
    require_once('Dao.class.php');
    require_once(
    'Bidder.class.php');

    class 
    BidderDao extends Dao
    {

        function 
    BidderDao()
        {
            
    parent::Dao('mysql://user:pass@localhost/auctions');
        }
        
        function 
    doDelete(&$obj)
        {
            
    $sql =
            
    '
                DELETE FROM
                    auction_bidders
                WHERE
                    id = ?
            '
    ;
            
    $stmt =& $this->conn->prepareStatement($sql);
            
    $stmt->setInt(1$obj->getId());
            
    $rs =& $stmt->executeUpdate();
        }
        
        function 
    doInsert(&$obj)
        {
            
    $sql =
            
    '
                INSERT INTO
                    auction_bidders (
                        id,
                        name,
                        email)
                VALUES
                        (?, ?, ?)
            '
    ;
            
    $id $this->conn->generateSequence('auction_bidders_seq');
            
    $stmt =& $this->conn->prepareStatement($sql);
            
    $stmt->setInt(1$id);
            
    $stmt->setText(2$obj->getName());
            
    $stmt->setText(3$obj->getEmail());
            
    $rs =& $stmt->executeUpdate();
            return 
    $id;
        }
        
        function &
    doLoad($id, &$rs)
        {
            return new 
    Bidder(
                
    $id,
                
    $rs->getString('name'),
                
    $rs->getString('email'));
        }
        
        function 
    doUpdate(&$obj)
        {
            
    $sql =
            
    '
                UPDATE
                    auction_bidders
                SET
                    name = ?,
                    email = ?
                WHERE
                    id = ?
            '
    ;
            
    $stmt =& $this->conn->prepareStatement($sql);
            
    $stmt->setText(1$obj->getName());
            
    $stmt->setText(2$obj->getEmail());
            
    $rs =& $stmt->executeUpdate();
        }
        
        function &
    find($id)
        {
            return 
    $this->abstractFind($id);
        }
        
        function &
    findForAuctionId($id)
        {
            
    $sql =
            
    '
                SELECT
                    id,
                    name,
                    email
                FROM
                    auction_bidders
                WHERE
                    auction_id = ?
                ORDER BY
                    name ASC
            '
    ;
            
    $stmt =& $this->conn->prepareStatement($sql);
            
    $stmt->setInt(1$id);
            
    $rs =& $stmt->executeQuery();
            return 
    $this->loadAll($rs);
        }
        
        function 
    findStatement()
        {
            return
            
    '
                SELECT
                    id,
                    name,
                    email
                FROM
                    auction_bidders
                WHERE
                    id = ?
            '
    ;
        }


    Dao.class.php:
    PHP Code:
    require_once('DaoRegistry.class.php');
    require_once(
    'DataSource.class.php');
    require_once(
    'ArrayList.class.php');

    class 
    Dao
    {

        var 
    $conn;
        
        function 
    Dao($dsn)
        {
            
    $this->conn =& DataSource::getConnection($dsn);
        }
        
        function &
    abstractFind($id)
        {
            
    $obj =& DaoRegistry::get($this$id);
            if (
    is_null($obj))
            {
                
    $stmt =& $this->conn->prepareStatement($this->findStatement());
                
    $stmt->setInt(1$id);
                
    $rs =& $stmt->executeQuery();
                
    $rs->next();
                
    $obj =& $this->load($rs);
            }
            return 
    $obj;
        }
        
        function 
    delete(&$obj)
        {
            if (! 
    is_null($obj))
            {
                
    $this->doDelete($obj);
            }    
        }
        
        function 
    doDelete(&$obj)
        {
        }
        
        function 
    doInsert(&$obj)
        {
        }
        
        function &
    doLoad($id, &$rs)
        {
        }
        
        function 
    doUpdate(&$obj)
        {
        }
        
        function 
    find()
        {
        }
        
        function 
    findStatement()
        {
        }
        
        function 
    insert(&$obj)
        {
            if (! 
    is_null($obj))
            {
                
    $obj->setId($this->doInsert($obj));
                
    DaoRegistry::put($this$obj->getId(), $obj);
                return 
    $obj->getId();
            }
        }
        
        function &
    load(&$rs)
        {
            
    $id $rs->getInt('id');
            
    $obj =& DaoRegistry::get($this$id);
            if (
    is_null($obj))
            {
                
    $obj =& $this->doLoad($id$rs);
                
    DaoRegistry::put($this$obj->getId(), $obj);
            }
            return 
    $obj;
        }
        
        function &
    loadAll(&$rs)
        {
            
    $objList =& new ArrayList();
            while (
    $rs->next())
            {
                
    $objList->append($this->load($rs));
            }
            return 
    $objList;
        }
        
        function 
    update(&$obj)
        {
            if (! 
    is_null($obj))
            {
                
    $this->doUpdate($obj);
            }
        }
        

    Since this post is already really long I won't inlcude the source for DaoRegistry.class.php, DataSource.class.php, ArrayList.class.php

    Usage example:
    PHP Code:
    $dao =& new BidderDao();
    $list =& $dao->findForAuctionId($_GET['auction_id']);
    $i =& $list->iterator();
    while (
    $i->hasNext())
    {
        
    $bidder =& $i->next();
        
    // do stuff with $bidder


  5. #5
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Haven't posted here, because I think I have stated my view on this already too often, but I completely agree with codezilla. I have used the DAO approach successfully several times now and it provides a great and standardized way of accessing data for me.
    I do things in avery similar way, but one or two qeustions: Codezilla, what does DaoRegistry do? And why do you often have "wrapper" methods here, like
    PHP Code:
    update(&$obj
        { 
            if (! 
    is_null($obj)) 
            { 
                
    $this->doUpdate($obj); 
    ? Perhaps you could post DaoRegistry as well? TIA

  6. #6
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mkrz
    what does DaoRegistry do?
    DaoRegistry makes sure that an object is only loaded once. For example, let's say I make several $dao->findForAuctionId() calls in single script:

    PHP Code:
    $dao =& new BidderDao();
    $list1 =& $dao->findForAuctionId($auction_id1);
    $list2 =& $dao->findForAuctionId($auction_id2);
    $list3 =& $dao->findForAuctionId($auction_id3); 
    And let's say a certain bidder is involved in all three auctions. DaoRegistry makes sure that only one Bidder object is instantiated for that bidder.

    Quote Originally Posted by mkrz
    Perhaps you could post DaoRegistry as well?
    Sure, here's the code:

    PHP Code:
    class DaoRegistry
    {

        var 
    $map = array();

        function 
    DaoRegistry()
        {
        }
        
        function &
    get(&$dao$key)
        {
            
    $this =& DaoRegistry::_getInstance();
            
    $dc get_class($dao);
            if (isset(
    $this->map[$dc][$key]))
            {
                return 
    $this->map[$dc][$key];
            }
        }
        
        function &
    _getInstance()
        {
            static 
    $instance;
            if (
    is_null($instance))
            {
                
    $instance = new DaoRegistry();
            }
            return 
    $instance;
        }
        
        function 
    put(&$dao$key, &$value)
        {
            
    $this =& DaoRegistry::_getInstance();
            
    $dc get_class($dao);
            if (! isset(
    $this->map[$dc]))
            {
                
    $this->map[$dc] = array();
            }
            
    $this->map[$dc][$key] =& $value;
        }
        

    Quote Originally Posted by mkrz
    And why do you often have "wrapper" methods here, like
    PHP Code:
    update(&$obj
        { 
            if (! 
    is_null($obj)) 
            { 
                
    $this->doUpdate($obj); 
    First, don't think of the load(), update(), insert(), and delete() methods as wrappers. Think of doLoad(), doInsert(), doUpdate(), doDelete(), find() and findStatement() as "hook" methods. Hook methods provide sub-classes with the ability to "hook" into the parent class in a pre-determined way. Any behavior common to all DAOs goes in the main methods (load(), update(), etc.). DAO-specific behavior goes in the hook methods (do*(), etc.). See how BidderDao is composed of only do*() and find*() methods?

    You're right though, Dao::update() and Dao::delete() don't do much. However, look at Dao::insert() -- it's doing something more useful. It's assigning the generated ID to the inserted object and adding it to the DaoRegistry. There's probably something useful that I could be doing in Dao::update and Dao::delete() -- I'm just not sure what that is yet. Mostly, I did them that way for the sake of consistency.

  7. #7
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah, some interesting ideas there. Will need a little time to think it through. Am I right in assuming that your DaoRegistry implements a Singleton pattern?

  8. #8
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yer, mkrz, looks very much like a Singleton Pattern to me anyways ?

  9. #9
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mkrz
    Am I right in assuming that your DaoRegistry implements a Singleton pattern?
    Yes! That's why the _getInstance() method is in there. The reason I implemented it as a Singleton is because for it to be useful, all DAOs need to have access to the the same instance. Making it a Singleton and requiring it to be accessing statically (i.e. using :: notation), makes it essentially a global object. And yes, globals ARE evil, but there are a couple circumstances where they are necessary -- and this is one of them.

  10. #10
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Looks interesting anyway, something for me to look into ? Apart from the Singleton pattern by HarryF at phppatterns.com, do you know of another article/tutorial on this pattern... @ Sun maybe ? Thanks in advance

  11. #11
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Can't think of a web tutorial right now, but for this pattern and all other "classic" pattern, the book "design patterns" by the so-called "gang of four" is an excellent resource. It's not exactly cheap though (as all software literature...)

  12. #12
    SitePoint Addict
    Join Date
    Mar 2003
    Location
    Germany
    Posts
    216
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry for slowly getting off-topic, but I don't quite understand this static access thing yet.

    What's the difference between

    PHP Code:
    DaoRegistry::get($this$id); 
    and

    PHP Code:
    DaoRegistry->get($this$id); 
    ?

    Hm, just remember that I read somewhere that with static access, you don't have to instantiate the object? But I still don't quite understand what I would need this for?

  13. #13
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Apart from the Singleton pattern by HarryF at phppatterns.com, do you know of another article/tutorial on this pattern... @ Sun maybe ? Thanks in advance
    Of course!

    http://www.dofactory.com/patterns/PatternSingleton.aspx
    http://home.earthlink.net/~huston2/dp/singleton.html
    http://www.google.com/search?q=singleton+design+pattern
    Last edited by codezilla; Jun 11, 2003 at 08:24.

  14. #14
    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 mkrz
    Sorry for slowly getting off-topic, but I don't quite understand this static access thing yet.

    What's the difference between

    PHP Code:
    DaoRegistry::get($this$id); 
    and

    PHP Code:
    DaoRegistry->get($this$id); 
    ?

    Hm, just remember that I read somewhere that with static access, you don't have to instantiate the object? But I still don't quite understand what I would need this for?
    For a static method to work, you can not have any references to $this in the method (because there is no instance). Other than that, they work the same (i.e. take parameters, return results, must have the class included before use, etc.).

    HTH
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  15. #15
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    must have the class included before use, etc
    As in the following ?
    PHP Code:
    DaoRegistry::get($this$id); 
    Looking at this, I see the method belongs to the parent class DaoRegistry ?

  16. #16
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for those links Codezilla... btw the google link threw an error but the first link will prove useful

  17. #17
    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)
    No, unlike some languages where :: is a scope resolution operator, in php :: is a way of accessing a class method directly without instanciating an instance of the class.

    Therefore:
    PHP Code:
    class foo {
    function 
    bar() {
     echo 
    "bar";
    }
    }

    foo::bar(); 
    will work and print bar, however

    PHP Code:
    class foo {
    var 
    b;
    function 
    foo() {
      
    $this->'bar';
    }
    function 
    bar() {
    echo 
    $this->b;
    }
    }

    foo::bar();  //this will error
    $f =& new foo;
    $f->bar(); //okay 
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  18. #18
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mkrz
    What's the difference between
    PHP Code:
    DaoRegistry::get($this$id); 
    and
    PHP Code:
    DaoRegistry->get($this$id); 
    ?
    Well, for one, "DaoRegistry->get($this, $id)" is not valid. The '->' operator only works with objects (like $dao) not with class names (like 'DaoRegistry'). However, the '::' operator works with both, although it has a slightly different purpose. Bascially, '::' is/should be used for static method calls. Static methods are kind of like regular functions except they must be called using their class name: Class::method().

    I used a Singleton with static methods in this case to ensure that every DAO accesses the exact same DaoRegistry instance.

    Quote Originally Posted by sweatje
    For a static method to work, you can not have any references to $this in the method (because there is no instance).
    True, although I cheated a bit by using a variable call '$this' in my static methods and setting it equal to the static instance.

  19. #19
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    As in the following ?
    PHP Code:
    DaoRegistry::get($this$id); 
    Looking at this, I see the method belongs to the parent class DaoRegistry ?
    I think sweatje just means you have to do this:
    PHP Code:
    include('DaoRegistry.class.php'); 
    Before you can do this:
    PHP Code:
    DaoRegistry::get($this$id); 

  20. #20
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Thanks for those links Codezilla... btw the google link threw an error but the first link will prove useful
    Oops! It's fixed now.

  21. #21
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Oh !! The second example I understand fully, though I was unaware that you could actually instantiate a method belonging to a class using :: in the way you've given in the first example ?Ummm... Didn't know that I thought :: was a reference to the parent class - maybe works that was also, since in your example (first) :: is not used in the scope of a class, correct ?

  22. #22
    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 Dr Livingston
    I thought :: was a reference to the parent class - maybe works that was also, since in your example (first) :: is not used in the scope of a class, correct ?

    You can use it inside of a class to access a parent method that you are overriding as well. This is an example of that (not tested code, off the top of my head):

    PHP Code:
    class foo {
    function 
    bar() {
    echo 
    'blah';
    }
    }

    class 
    son_of_foo {
    function 
    bar() {
      
    parent::bar();
      echo 
    'zaa';
    }

    is accessing the parent class method. In this case, you could equally do foo::bar() because the access is static. I do not recall right now if you can access a non-static method (one that references $this) using the parent:: syntax, but I think you can.

    HTH
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  23. #23
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    . . . I was unaware that you could actually instantiate a method belonging to a class using :: in the way you've given in the first example
    Be careful with your terminology there. You instantiate objects (i.e., an object is an "instance" of a class). Methods are "called", or "invoked".

    http://whatis.techtarget.com/definit...212355,00.html

    Quote Originally Posted by Dr Livingston
    I thought :: was a reference to the parent class - maybe works that was also, since in your example (first) :: is not used in the scope of a class, correct ?
    'parent' is used to refer to the parent class. You've probably seen something like this:
    PHP Code:
    class SubClass extends SuperClass()
    {
        function 
    SubClass()
        {
            
    parent::SuperClass();
        }

    Well, you could also do this:
    PHP Code:
       function SubClass()
        {
            
    SuperClass::SuperClass();
        } 
    Or even this:
    PHP Code:
       function SubClass()
        {
            
    $this->SuperClass();
        } 
    That's why '::' is kind of weird. You'd think in the first example that SubClass was accessing SuperClass's constructor statically, but it's not. I think that's why there's a lot of confusion surrounding the '::' operator because it doesn't behave in a consistent manner.
    Last edited by codezilla; Jun 11, 2003 at 11:32.

  24. #24
    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 codezilla
    Or even this:
    PHP Code:
        function SubClass()
        {
            
    $this->SuperClass();
        } 
    The reason that you need the parent:: is if you are overriding the method in the subclass, then $this->method() will only access the subclass method, you would have to use the parent:: to get to the superclass method.
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  25. #25
    SitePoint Zealot codezilla's Avatar
    Join Date
    Nov 2002
    Location
    upstairs
    Posts
    110
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Not sure if your implying '$this->SuperClass();' won't work in my example -- because it does (since SubClass is not overriding it).

    Also, 'parent::method()' is valid notation for calling any method in the parent class, not just overrided methods. In fact, I use it sometimes for no other reason than to clearly indicate that an inherited method is being called. But you're absolutely correct, sweatje, sometimes 'parent::method()' is the only way to access an overrided method.


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
  •