SitePoint Sponsor

User Tag List

Results 1 to 23 of 23
  1. #1
    SitePoint Member
    Join Date
    Jun 2004
    Location
    brazil
    Posts
    13
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Data access object

    I ave seen a lot of threads discusting the creation of classes for accessing and fetching db fields.

    I read a lot of articles... about patterns and stuff... and instead of getting a good solution.. Im becoming confused...

    What is the best way... creating a statement class?

    Creating specific classes.. like Article.. Author?

    Spliting the aplication into in layers?

    Please.. give some help fellows.

    Sorry about my english.

  2. #2
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Creating specific classes.. like Article.. Author?
    This is the way I do it anyways. I've reposted some script I had seen on these forums the other day there, so you have an example to start with

    PHP Code:
    ...
    class 
    PersonMapper 
        function &
    findByLastName($name) { 
            
    $sql 'SELECT id, lastname, firstname ' 
                   
    'FROM people ' 
                   
    'WHERE lastname LIKE ' $name 
                   
    'ORDER BY lastname'
            
    $rs $this->db->query($sql); 
            return 
    $this->loadAll($rs); 
        } 
        function &
    doLoad($row) { 
            
    $person = new Person(); 
            
    $person->setID($row['id']); 
            
    $person->setLastName($row['lastname']); 
            
    $person->setFirstName($row['firstname']); 
            return 
    $person
        } 
        function &
    loadAll($rs) { 
            
    $result = array(); 
            while (
    $row $rs->fetch()) { 
                
    $result[] = $this->doLoad($row); 
            } 
            return 
    $result
        } 

    ... 
    Not my script of course, but I cannot remember the thread, nor the person who did post the original script

    You know who you are though, if you come across this thread you can claim some fame

  3. #3
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    On the otherhand, the way I do it is like so, below

    PHP Code:
    # login.packages.php

    class UserRoles {
            function 
    UserRoles() {
            } 
    # constructor not implemented
            
            
    function Load( &$resultset$archiver ) {
                
    $indexer = array();
                
    $iterator = &new QueryIterator( &$resultset );
                
                while( 
    $iterator -> IsValid() ) {
                    
    $row $iterator -> GetCurrent();
                    
    $iterator -> GetNext();
                    
                    
    $archive = &new $archiver;
                    
    $archive -> Invoke$row );
                    
                    
    $indexer[] = &$archive;
                }
                return 
    $indexer;
            }
            
            function 
    Insert() {
            }
            
            function 
    Update() { 
            }
            
            function 
    Delete() { 
            }
        }
        
        class 
    UserRolesGateway {
            function 
    UserRolesGateway() {
            } 
    # constructor not implemented
            
            
    function InsertUsers2Roles( &$db$role_id$user_id ) {
                
    $users2Roles "INSERT INTO tbl_users2roles SET 
                    fld_role_id = '"
    .$role_id."',
                    fld_user_id = '"
    .$user_id."'";
                    
                return 
    $db -> Execute$users2Roles );
            }
            
            function 
    FindAll( &$db ) {
                
    $findAll "SELECT 
                    fld_id AS id, 
                    fld_role_name AS name FROM 
                    tbl_roles ORDER BY fld_id"
    ;
                    
                return 
    $db -> Execute$findAll );
            }
            
            function 
    FindByUserId( &$db$id ) {
                
    $findByUserId "SELECT 
                    fld_user_id AS user_id,
                    fld_role_id AS role_id,
                    fld_id AS id,
                    fld_role_name AS name FROM
                    tbl_users2roles, 
                    tbl_roles WHERE 
                    fld_user_id = '"
    .$id."' AND fld_role_id = fld_id ORDER BY fld_role_id";
                    
                return 
    $db -> Execute$findByUserId );
            }
            
        }
        
        class 
    RolesArchiver {
            var 
    $Id;
            var 
    $Name;
            
            function 
    RolesArchiver() {
            }
            
            function 
    Invoke$row ) {
                
    $this -> Id      $row['id'];
                
    $this -> Name      $row['name'];
            }
        }
        
        class 
    UserPermissions {
            function 
    UserPermissions() {
            } 
    # constructor not implemented
            
            
    function Load( &$resultset$archiver ) {
                
    $indexer = array();
                
    $iterator = &new QueryIterator( &$resultset );
                
                while( 
    $iterator -> IsValid() ) {
                    
    $row $iterator -> GetCurrent();
                    
    $iterator -> GetNext();
                    
                    
    $archive = &new $archiver;
                    
    $archive -> Invoke$row );
                    
                    
    $indexer[] = &$archive;
                }
                return 
    $indexer;
            }
            
            function 
    Insert() { 
            }
            
            function 
    Update() { 
            }
            
            function 
    Delete() { 
            }
        }
        
        class 
    UserPermissionsGateway {
            function 
    UserPermissionsGateway() {
            } 
    # constructor not implemented
            
            
    function FindByRoleId( &$db$id ) {
                
    $findByRoleId "SELECT 
                    fld_perm_id AS perm_id,
                    fld_role_id AS role_id,
                    fld_id AS id,
                    fld_perm_name AS name FROM 
                    tbl_roles2perms,
                    tbl_permissions WHERE 
                    fld_perm_id = fld_id AND 
                    fld_role_id = '"
    .$id."' ORDER BY fld_perm_id";
                    
                return 
    $db -> Execute$findByRoleId );
            }
            
        }
        
        class 
    PermissionsArchiver {
            var 
    $Id;
            var 
    $Name;
            
            function 
    PermissionsArchiver() {
            }
            
            function 
    Invoke$row ) {
                
    $this -> Id      $row['id'];
                
    $this -> Name      $row['name'];
            }
        }
        
        class 
    LogIn {
            function 
    LogIn() {
            } 
    # constructor not implemented
            
            
    function Load( &$resultset$archiver ) {
                
    $indexer = array();
                
    $iterator = &new QueryIterator( &$resultset );
                
                while( 
    $iterator -> IsValid() ) {
                    
    $row $iterator -> GetCurrent();
                    
    $iterator -> GetNext();
                    
                    
    $archive = &new $archiver;
                    
    $archive -> Invoke$row );
                    
                    
    $indexer[] = &$archive;
                }
                return 
    $indexer;
            }
            
            function 
    Insert() { 
            }
            
            function 
    Update() { 
            }
            
            function 
    Delete() { 
            }
        }
        
        class 
    LogInGateway {
            function 
    LogInGateway() {
            } 
    # constructor not implemented
            
            
    function FindByLogIn( &$db$username$password ) {
                
    $findByLogIn "SELECT
                    fld_id,
                    UNIX_TIMESTAMP( fld_date ) AS fld_date,
                    fld_state,
                    fld_fname,
                    fld_lname,
                    fld_email,
                    fld_session,
                    fld_username,
                    fld_password FROM tbl_login WHERE 
                    fld_username = '"
    .$username."' AND 
                    fld_password = PASSWORD('"
    .$password."')";
                    
                return 
    $db -> Execute$findByLogIn );
            }
        }
        
        class 
    LogInArchiver {
            var 
    $Id;
            var 
    $Date;
            var 
    $State;
            var 
    $FName;
            var 
    $LName;
            var 
    $EMail;
            var 
    $Session;
            var 
    $Username;
            var 
    $Password;
            
            function 
    LogInArchiver() {
            } 
    # constructor not implemented
            
            
    function Invoke$row ) {
                
    $this -> Id         =    (int)         $row['fld_id'];
                
    $this -> Date         =    (string)     $row['fld_date'];
                
    $this -> State         =    (string)    $row['fld_state'];
                
    $this -> FName         =    (string)    $row['fld_fname'];
                
    $this -> LName         =    (string)    $row['fld_lname'];
                
    $this -> EMail         =    (string)    $row['fld_email'];
                
    $this -> Session     =    (string)    $row['fld_session'];
                
    $this -> Username     =    (string)    $row['fld_username'];
                
    $this -> Password     =    (string)    $row['fld_password'];
            }
        } 
    PHP Code:
    # ie
    $db singleton::getInstance();
                        
    $login LogIn::LoadLogInGateway::FindByLogIn( &$db$username$password ), 'LogInArchiver' ); 

  4. #4
    SitePoint Member
    Join Date
    Jun 2004
    Location
    brazil
    Posts
    13
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey... thanks for the help..
    I'm going to look the code later... I probably have a lot to study now...

  5. #5
    SitePoint Zealot
    Join Date
    Dec 2003
    Location
    with my kids
    Posts
    116
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What is the best way
    really, nobody knows. nobody will admit this though. it's why everyone does it slightly different and your largely confused. "the best way" is always slightly different for every case. you can generalize for most cases (i.e. patterns), but they all need to be tweaked to fit your requirements. about the best you can say with any degree of certainty is that it is good to have your data available to your application code without respect to where the data came from (i.e. storage mechanism) or how it got there (which pattern, abstraction, etc.).

  6. #6
    SitePoint Addict
    Join Date
    Apr 2002
    Posts
    330
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Siegfried
    I ave seen a lot of threads discusting the creation of classes for accessing and fetching db fields.

    I read a lot of articles... about patterns and stuff... and instead of getting a good solution.. Im becoming confused...

    What is the best way... creating a statement class?

    Creating specific classes.. like Article.. Author?

    Spliting the aplication into in layers?
    Before reinventing the wheel, you may want to take a look at Metastorage. This is a data access object generator tool that lets you design models of your data access classes in a simple XML format. Your class models include the variables, validation rules, relationships between classes and functions that implement the aspects that you need to manipulate your data access objects.

    Then Metastorage generates all the necessary PHP classes a few seconds, including one to install the database schema with the tables that will store the data access objects.

    Other than that, Metastorage features an Object Query Language that lets you perform arbitrary searches for objects of the data classes or belong to specific relation scripts, all without having to write a single line of SQL code by hand.

    It also features the ability to generate common types of Web based forms for creating your data objects, generates UML (graphical) diagrams that show all generated classes.

    Metastorage in mainly a command line tool but there is now a Web interface to setup and run the Metastorage compiler. Here are some screenshots. BTW, some people do not believe it, but these are really screenshots of the Web interface, not a desktop GUI interface. ;-)
    Last edited by mlemos; Jun 17, 2004 at 08:54. Reason: Fixed the screenshots page address.
    Manuel Lemos

    Metastorage - Data object relational mapping layer generator
    PHP Classes - Free ready to use OOP components in PHP

  7. #7
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Before reinventing the wheel, you may want to take a look at Metastorage. This is a data access object generator tool that lets you design models of your data access classes in a simple XML format. Your class models include the variables, validation rules, relationships between classes and functions that implement the aspects that you need to manipulate your data access objects.
    Yes, yes, we are all aware of your Meta storage class(es), and without sounding ignorant or bad mannered, personally I'm fed up to the back teeth of hearing all about it over, and over, and .... over again

    Please, can you change the tune huh ?

    To benifit yourself, and to save my sanity maybe Harry or an administrator could post a link in the advanced resources thread, if it hasn't already been done that is ?

    Then everyone is happy

  8. #8
    SitePoint Addict
    Join Date
    Apr 2002
    Posts
    330
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Widow Maker
    Yes, yes, we are all aware of your Meta storage class(es), and without sounding ignorant or bad mannered, personally I'm fed up to the back teeth of hearing all about it over, and over, and .... over again

    Please, can you change the tune huh ?
    You are sounding bad mannered because my message was not meant specifically to you but rather to answer the original poster.

    The fact that you are already aware of whatever packages I tell about is perfectly irrelevant. You could just ignore my message. Instead you decided to post a public criticism to my message as if I am not trying to help the original poster and my message is a personal threat to your sanity.

    If you really want to me to not try to help other people with my packages, how about stopping the hipocrisy and tell me directly in a private message, instead of making a said spectacle of this thread?

    If you do not mind me trying to help other people with my packages, how about just ignoring my messages?
    Manuel Lemos

    Metastorage - Data object relational mapping layer generator
    PHP Classes - Free ready to use OOP components in PHP

  9. #9
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Widow Maker
    without sounding ignorant or bad mannered
    Too late.

    In fact, I haven't seen it before and it looks like an awesome idea.
    Code generation is by far the best idea I've seen. If an entire section of an appliction can be completely generated with no further modification, then when a modificaiton to the specification is required, only a modification to the specification of the code to be generated is needed and you simply re-generate everything.

    The ultimate point is to develop faster with less hassle, and this is a brilliant idea.

  10. #10
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)


    Sorry Appologies all around for any offence caused, none was intended, I assure you

  11. #11
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    VA, USA
    Posts
    57
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Widow Maker
    To benifit yourself, and to save my sanity maybe Harry or an administrator could post a link in the advanced resources thread, if it hasn't already been done that is ?

    Then everyone is happy
    I think this would be a great idea. I can sympathise with Manuel on this issue, but I can also see why it pisses people off.

    Before criticizing Manuel, do bear in mind that his post is on-topic and that the software he is shamelessly plugging (yes, again & again & again) is open-source, free softare. He's not making a profit from people using his tools and certainly he has invested a lot of time & thought in these products. I don't agree with Manuel's methodology (or lack of tact), but I certainly respect his work.

    Moreover, as someone who happens to be lead on a rather similar project, I can understand how it's kinda frustrating to see people post again & again "how do you rcommend I do DAO in PHP?" There are a number of DAO projects in PHP which have invested a lot of thought and sourcecode in the question of how to do this DAO stuff in a good, portable way. So, while it's true that Manuel suggests Metastorage again & again, it's also true that users are asking the same question again & again.

    Of course, if a user has a specific question about DAO or found Metastorage (or any of the others) defficient for a particular need, it would be great to hear about that -- and the dialog would be different ('course I'm not saying you wouldn't hear from Manuel . The inquiries I've typically seen, however, tend to be people asking for advice on a re-invention of database DAO w/o any mention of the existing PHP tools for the job.

    So, I'd just say that before re-creating a basic PHP component, try a search on freshmeat.net or google: "php object persistence", "php dao", "php orm". Of course if you just want to re-create things, then that's different In the end, though, most of us (I assume Manuel included) would be very happy to have someone come and post suggestions or wish lists to our dev lists. It's open-source, afterall.

    Cheers,
    Hans

  12. #12
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by hlellelid
    So, while it's true that Manuel suggests Metastorage again & again, it's also true that users are asking the same question again & again.
    Exactly. I fail to see why someone should be criticised for trying to help. One might criticise other posters for "spamming" the boards with a message in almost every topic but nothing to say.

  13. #13
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There was 2 points that were a problem for me, which were

    1) A running explamation of Metastorage from the point of use of Manuel's classes, which has been posted more than several times over recent months - blatantly promotion if I ever seen it

    2) There was no other solution given either, something which I've noted as well in Manuel's postings.

    But anyways, it's all water under the bridge so to speak, I'm not one for holding a grudge, etc

  14. #14
    SitePoint Addict melchiorus's Avatar
    Join Date
    Jun 2004
    Location
    Indiana
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is offtopic but, is doing something like this:

    Code:
    $var::class_function();
    The same as doing this:

    Code:
    $var->class_function();
    When calling a class function or something? I noticed it in some of the code examples you have...
    -Melchior (Stephen Craton)

  15. #15
    SitePoint Enthusiast
    Join Date
    Aug 2003
    Location
    VA, USA
    Posts
    57
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Widow Maker
    1) A running explamation of Metastorage from the point of use of Manuel's classes, which has been posted more than several times over recent months - blatantly promotion if I ever seen it

    2) There was no other solution given either, something which I've noted as well in Manuel's postings.
    Yes and I agree that those are good points. I know why it irritates people; it's the same case on mailing lists like php-db. Certainly Manuel has garnished a reputation for this broadcast-style product promotion.

    I think the suggestion that there be a link added to the forum you mentioned was a very good one. Indeed, I think people should be aware that Metastorage is out there. I haven't looked much at that forum myself, but perhaps a single post that enumerated the PHP DAO solutions -- with descriptions, such as the one Manuel provided above -- would be great.

    Hans

  16. #16
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi...

    Why don't we have a FAQ?

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  17. #17
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    An FAQ might work well actually, much like Site Points Blogs ?

  18. #18
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by melchiorus
    This is offtopic but, is doing something like this:

    Code:
    $var::class_function();
    The same as doing this:

    Code:
    $var->class_function();
    When calling a class function or something? I noticed it in some of the code examples you have...

    This is a static method:
    PHP Code:
    $var::class_function(); 
    This is a normal (non-static?) method
    PHP Code:
    $var->class_function(); 
    A static method is basically just a function that is in a class.
    It can not have references to the class as an object (i.e. $this->). It must be an independant function seperate from the rest of the object.

    The point of putting it in a class, is that it would logically belong in the class along with the classes functionality. For example, you might have a DB class with a method 'GetDBMS($arg)' that returns a subclass of DB, so you would call

    $db = DB::GetDBMS($arg);

    So essentially, a static method, is a lone function that happens to sit inside a class. And can be called with the :: operator

    Hope that was somwhat clearer than mud :-P

    Regards,
    Eli

  19. #19
    SitePoint Addict melchiorus's Avatar
    Join Date
    Jun 2004
    Location
    Indiana
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Made perfect sense actually, thanks for the explanation!
    -Melchior (Stephen Craton)

  20. #20
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't see the point of instantiating a class for SESSIONs so I use a class with all class methods are static, and it works okay

    Likewise for the database layers as well btw

  21. #21
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeh, I use it for DB layers also. But you have to be careful not to use too many static methods in your code, because then you get away from OOP and move back into proceedural mode where you just have lots of functions - even tho it is in a class, it is still just a list of functions.

    It does have a place, just use it sparingly

  22. #22
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, don't go over the top, though I still see it as being Obj Oriented Programming

    Procedural Prog is for the script kiddies, OO Programming is for real developers

  23. #23
    SitePoint Guru
    Join Date
    Dec 2003
    Location
    oz
    Posts
    819
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Widow Maker
    Procedural Prog is for the script kiddies, OO Programming is for real developers
    Well, I don't see it like that.

    I've had to modify a lot of awful proceedural code, and realised that 80-90% of time doing modifications on a system with no design is understand the code before even doing any coding. So productivity runs at about 10-20%.

    The lack of productivity - and hence job satisfaction - made the jobs annoying instead of fun, and now understand why most of my friends who graduated with me don't ever want to program in their IT careers.

    But learning OO Design makes modification fast and efficient. And when it's designed well, its fun and absurdly easy to use.


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
  •