SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 31

Thread: class question

  1. #1
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    class question

    I'll simplify my problem using a common implentation.

    Say i have a database of users.
    I have a class called User, and when an instance of this class is created for a specific user id it reads the data from the mysql database and stores it in private User class variables, which are accessed by getter functions...pretty standard stuff I believe.

    But I'm having problems coming up with the best way of accessing ALL the users. I could easily just use "SELECT * FROM users_table" and process the returned array without using classes etc, but I believe in OOP, so what I did was to create another class called Users (notice the plural), which deals with all the users. When an instance of this class is created, it fills the class with all the users infos.

    But I can't help thinking that there's a better way of doing it. I'm using 2 classes. I could just use the User class, and get the user's one by one, but then I couldn't use mysql "order by" to sort them alphabetically. (not that sorting is a priority, there's other reaons...using 2 classes seems a bit pointless)

    Anyone have any insights?

    Thanks.

  2. #2
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Well, you could have a master class called users, which returns an array of objects from the "user" class - you could then access each individual user object, or fetch all.
    for example
    PHP Code:
    <?
    class Users{
       var 
    $userArray;
       function 
    __construct(){
          
    $q mysql_query("SELECT * FROM users_table");
          while(
    $row mysql_fetch_array($q)){
             
    $this->userArray[$username] = new User($username);
          }
       }
       function 
    get_all_users(){
          return 
    $this->userArray;
       }
       function 
    get_user($username){
          return 
    $this->userArray[$username];
       }
    }
    class 
    User{
       var 
    $userid$username;
       function 
    __construct($username){
          
    $q mysql_query("SELECT * FROM `users_table` WHERE `username`='".$username."'");
          
    $this->userid mysql_result($q0'id');
          
    $this->username mysql_result($q0'username');
       }
       function 
    getUserId(){
          return 
    $this->userid;
       }
    }
    then you could use something like:
    PHP Code:
    <?
    $users 
    = new Users;
    $userarray get_all_users();
    foreach(
    $userarray as $user){
        echo 
    $user->getUserId();
    }
    Hope that helps.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  3. #3
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    that looks good, thanks!

    this is my first major php project for a while, i'm a bit rusty

  4. #4
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    no, it won't be as useful as my example - you may want to look up OOP Design Patterns:
    http://www.ibm.com/developerworks/li...p-designptrns/
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  5. #5
    rajug.replace('Raju Gautam'); bronze trophy Raju Gautam's Avatar
    Join Date
    Oct 2006
    Location
    Kathmandu, Nepal
    Posts
    4,013
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What is the problem to create separate method/function in the same class and get it?
    Mistakes are proof that you are trying.....
    ------------------------------------------------------------------------
    PSD to HTML - SlicingArt.com | Personal Blog | ZCE - PHP 5

  6. #6
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    because it's not truelly OOP then - you'd have to keep on selecting users, then echoing something, then select next user, etc. With my example, he could use a double-oop structure. Every item of the array would be an object of it's own.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  7. #7
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    arkinstall,
    yes, I think your's is good OOP.
    If i want to access ALL users (say for a userlist), then i can use the USERS class...but if i want to access just ONE user (say for a user bio page), then i can use USER.......but the USERS class is full of USER classes so that's good.

    Cheers!

  8. #8
    SitePoint Addict
    Join Date
    Aug 2005
    Posts
    207
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I in some way I understand your dilemma, but then I tend to look at it in a different way. Even so, I think it doesn't have anything to do with logic, it has more to do with personal style.

    Take for example an application like a forum or mail system, it's the community that derives from the application, not from a single unique user. So wouldn't the user be loaded at start up, whether they be a member or visitor. So in that case, I don't see where a class called user is needed, because the base class community should already have the (user, groups belonging to, user permission) information, from maybe an authorize class because application access is based on the type of user, so the authorize class, would contain the application access key (session table) or better said, all the information for any user accessing the application. Now that not saying you shouldn't have a users class to access all the users, in fact I would, because that would be something that is unique, which if it isn't part of the applications initialization, then a users class is needed, but the user class isn't needed.

    I think people in general, including myself, think that because we logically think that relationships are the best way to look at things, we tend to create to many relationships, which is always worse than to few.

  9. #9
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Ah, however if you where to think of each user as an object, which holds all access details, then the "authorise" class isn't needed - in fact, it has one job.

    If, in the users class, you had a variable "authorised", with a value. you could then reproduce the entire productivity of the "authorised" class, with a simple function - User->isAuthorised.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  10. #10
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    Hey Jace, you might be interesting in looking at SPL it could add some functionality to that class.

    http://www.phpro.org/tutorials/Introduction-to-SPL.html
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  11. #11
    Obey the Purebreed trib4lmaniac's Avatar
    Join Date
    Dec 2004
    Location
    Cornwall, UK
    Posts
    594
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arkinstall View Post
    PHP Code:
    <?
    class Users{
       var 
    $userArray;
       function 
    __construct(){
          
    $q mysql_query("SELECT * FROM users_table");
          while(
    $row mysql_fetch_array($q)){
             
    $this->userArray[$username] = new User($username);
          }
       }
       function 
    get_all_users(){
          return 
    $this->userArray;
       }
       function 
    get_user($username){
          return 
    $this->userArray[$username];
       }
    }
    class 
    User{
       var 
    $userid$username;
       function 
    __construct($username){
          
    $q mysql_query("SELECT * FROM `users_table` WHERE `username`='".$username."'");
          
    $this->userid mysql_result($q0'id');
          
    $this->username mysql_result($q0'username');
       }
       function 
    getUserId(){
          return 
    $this->userid;
       }
    }
    One slight problem with this particular approach:
    PHP Code:
    $arkinstall = new User("arkinstall");

    $users = new Users();
    foreach (
    $users->get_all_users() as $user)
    {
        if (
    $user->getUserId() == $arkinstall->getUserId())
        {
            
    $user == $arkinstall// This is false.
            
    break;
        }

    Although a situation like this is not unworkable, it is (most likely) undesirable. You would want the User and Users classes to cooperate with each other.

    Also, what if you do not want to get all of your users from the database? Suppose you just want to retrieve the latest user to register at your site. As it stands, you would have to pull back every user and loop through them individually, checking their registration dates as you go.
    I would describe this as "superinefficient."

  12. #12
    SitePoint Addict
    Join Date
    Aug 2005
    Posts
    207
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arkinstall View Post
    Ah, however if you where to think of each user as an object, which holds all access details, then the "authorise" class isn't needed - in fact, it has one job.

    If, in the users class, you had a variable "authorised", with a value. you could then reproduce the entire productivity of the "authorised" class, with a simple function - User->isAuthorised.
    That's point I was making, it's about style. But application initialization really removes the need for anything relating to user details, my authorization class idea, has more to do with the complete application access logic, not just authorizing a unique user at application initialization. Just think of the things that need to be done, every time the application starts. insert or update the session, update the user, set or remove cookies, if login attempt, protect from brute force attacks, block access to pages that member already logged in shouldn't be requesting. Authorization relates to all those things and more, because a user can not be given or denied access without any of those methods.

  13. #13
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    Thumbs up

    It was an example... but in that case, you could easily modify it:
    PHP Code:
    <?
    class Users{
       var 
    $userArray;
       function 
    __construct($where=""){
          if(!
    is_null($where)){
             
    $q mysql_query("SELECT * FROM users_table");
          }else{
             
    $q mysql_query("SELECT * FROM users_table ".$where);
          }
          while(
    $row mysql_fetch_array($q)){
             
    $this->userArray[$username] = new User($username);
          }
       }
        function 
    get_all_users(){
          return 
    $this->userArray;
       }
       function 
    get_user($username){
          return 
    $this->userArray[$username];
       }
    }
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  14. #14
    Obey the Purebreed trib4lmaniac's Avatar
    Join Date
    Dec 2004
    Location
    Cornwall, UK
    Posts
    594
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arkinstall View Post
    It was an example... but in that case, you could easily modify it:
    PHP Code:
    <?
    class Users{
       var 
    $userArray;
       function 
    __construct($where=""){
          if(!
    is_null($where)){
             
    $q mysql_query("SELECT * FROM users_table");
          }else{
             
    $q mysql_query("SELECT * FROM users_table ".$where);
          }
          while(
    $row mysql_fetch_array($q)){
             
    $this->userArray[$username] = new User($username);
          }
       }
        function 
    get_all_users(){
          return 
    $this->userArray;
       }
       function 
    get_user($username){
          return 
    $this->userArray[$username];
       }
    }
    Surely one of the major benefits of encapsulating your users inside a class is the fact that you no longer have to worry about the way they are stored, the structure behind them, the SQL needed for particular queries etc.

    Also, it does not address the identity problem. Calling "new User($name)" on separate occasions will still create two different objects.

  15. #15
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think all this talk about "authorisation" and user permissions is going off topic slightly...the example was JUST a list of users, nothing to do with them logging in or having website permissions....
    let me be more specific with my example....what about a simple gig list for a band....we have a page to "list all gigs", and a page to "list one gig" (for further details about this ONE gig, e.g address).

    (not that i'm making a website that has anything to do with gigs, i just thought it was a good example )

  16. #16
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hmmm..just started coding all this and remebered I'm forced to use PHP4...which doesn't really implement classes properl

  17. #17
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    the only main problme would be that you have to rename __construct() to the name of the class, e.g. function Users().

    Edit:

    Also, in the Users class you would need to add the pointer to the array, e.g.
    PHP Code:
          while($row mysql_fetch_array($q)){
             
    $this->userArray[$username] =& new User($username);
          } 
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  18. #18
    SitePoint Member
    Join Date
    Oct 2007
    Location
    East Sussex
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What you're after is a design pattern called the data mapper. Can't remember the full implementation but its similar to what you're describing above. Something like

    Code:
    class User_Mapper{
       protected $_userData = array();
       protected $_userObjects = array();
       
       public function __construct(){      
       }
       
       function get_all_users(){      
       		if(empty($this->_userObjects))
       		{
       			if(empty($this->_userData)){
       				 $this->_loadUser();
       			}
       			
       			foreach ($this->_userData AS $data)
       			{
       				$this->_addUser($data);
       			}   			
       		}
       		
       		return $this->_userObjects;
       }
       
       function get_user($username){
       		if(isset($this->_userObjects[$username]))
       		{
       			return $this->_userObjects[$username];
       		}
       		
       		if(isset($this->_userData[$username]))
       		{
       			$this->_addUser($this->_userData[$username]);
       			return $this->_userObjects[$username];
       		}
       		
       		$this->_loadUser($username);
       		$this->_addUser($this->_userData[$username]);
       		return $this->_userObjects[$username];
       }   
       
       protected function _loadUser($username=null) // null would load all users
       {
       		// sql select user
       		$result = Get all results from db as associative array
       		foreach ($result AS $user)
       		{
       			$this->_userData[$user['username']] = $user;
       		}
       }
       
       protected function _addUser($data)
       {
       		$this->_userData[$data['username']] = new User($data);
       }
    }
    
    class User{
       var $userid, $username;
       function __construct($data){
          $this->userid = $data['userid'];
          $this->username = $data['username'];
       }
       function getUserId(){
          return $this->userid;
       }
    }
    ?>
    This is a very simplified version (you should abstract much out into a class something like Mapper_Abstract) but i think its the right idea, however im sure googling datamapper would return better results!

  19. #19
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i think there's more to it than just changing __counstruct()...like,it was a while since I looked into it last, but there's lots of problems with referencing classes in PHP4, amongst other things.
    php4 doesn't even like the syntax of this.
    echo $users->get_user($id)->get_name();

  20. #20
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    well, change it to:
    PHP Code:
    <?
    $user_2 
    $users->get_user(2);
    echo 
    $user_2->get_name();
    anywho, why do you need to work on a php4 server? time to upgrade, methinks.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  21. #21
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    haha ye..i hate working on php4, but i'm with a REALLY good hosting company..the only bad thing is php4....everyone is asking for 5, but it's their belief that it's better to wait for version 6.
    in fact..i hate php....i'd love to user a PROPER programming language like C++ (which is what asp.net allows, rite?)...in fact..i mite start making websites in qbasic

    ah rite, ye, the below does work...i was getting mixed up with my PHP4 CLASS REFERENCES

    $user_2 = $users->get_user(2);

    echo $user_2->get_name();

  22. #22
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    you must be crazy. lol.

    I've worked with C#, VB (shivers in hate), C, C++, Perl, you name it. Nothing compares to PHP in the slightest.

    For one, C++ is available in ASP.net, however the methods are different, even though the technique is the same. This practically means it's a different language.

    Secondly, there is no community better than PHP's. These forums alone have thousands of people on - alot of which go to the PHP forums.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  23. #23
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    haha ye...but that's because php is free and everyone hates Microsoft....basically, i hate any programming language where u don't have to declare variables as standard (php, actionscript), or languages which don't have strict datatypes....sure, it's convienent to be able to add 5 to 'hello' and get 'hello5' instead of an error, but it causes too much headache in the long run.

    but i ges php5 is good, i've never used it...i imagine it improves on php4 a lot.

  24. #24
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    alot. It's much better in almost every way.
    it's convienent to be able to add 5 to 'hello' and get 'hello5' instead of an error.
    actually, you're mistaken:
    PHP Code:
    echo "hello"+5//output: 5 
    you're thinking of "hello".5, not addition.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  25. #25
    SitePoint Enthusiast
    Join Date
    Nov 2006
    Posts
    63
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arkinstall View Post
    actually, you're mistaken:
    PHP Code:
    echo "hello"+5//output: 5 
    you're thinking of "hello".5, not addition.
    ye, that's what I mean...you should HAVE to convert 5 into a string before you add it to a string (using the dot operator)...
    if it's good enough for qbasic:
    mystring = "hello"+5 <---- error
    mystring = "hello" +str(5) <----correct

    and even so...why the heck does
    echo "hello"+5
    display 5 anyway! that shud be an error...too userfriendly.

    ... also javascript let's u do myvar = 'hello' + 5....but let's not get onto javascript...


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
  •