功能抽象

Just a quick question regarding re-useable code.

Ive lately been trying to modularise my code. I'm not really good with OO PHP yet (im working towards getting my head around it all) but even if i started using OOP there are a number of scenarios like the one below, where i see an issue with abstracting my code.

So lets say i have a list of users that have posted a comment in a news article. When i get the list of the comments, all i have is the user id. Before i started trying to abstract functionaility, i would have just done something like

SELECT c.*, u.username FROM comments AS c LEFT JOIN users AS u ON c.uid = u.id WHERE c.news_id = 90

This would give me the comment along with the username of who posted it. Now in order to abstract out the retrival of the username (lets say if the username was null, i may want to return the concat of fname and sname) i could do something like this. (bare in mind its an example, i know in most cases username would be a required registration field, imagine im building a base system for developing new sites where the username could be something other than a string in the database).

function getUsername($uid) {
  return /** the username from the database however i decide to get it **/
}

That would have to run at least 1 mysql query. If i have 100 comments on display, that could be 100 queries being run

In OOP i guess i would do something like

$user = new User($uid);
echo $user->getUsername();

But that would also require a query to load the user (and probably be slightly more resource intensive as a user class would get far more information on init to build the user object for all the possible methods to follow.

I know i could use memcache or something to speed things up. Even cache the results so subsequent getUsername() calls with the same uid doesnt require another query. But ni cant think of a solution that comes anywhere near to being as good as getting the username in my usual way (first code snippet).

Am i looking too deep into function abstraction and trying to over use OOP? I dont think so personally, I think its a perfectly valid requirement, and it would make sense to instantiate a user object if i were to be using OOP?

Just looking for some pointers really. Will abstraction functionaility always impact performance? Or am i just going about it the wrong way ?

Whilst cleaning up my account i thought it best to close some old questions. What i found is pretty obvious and i had a feeling i knew it all along. For anyone else that is wondering the same as i was and find's this post. The basic premise is it's your decision.

Basically you can fully abstract your methods so their completely standalone and suffer some pretty major performance issues, or at the other end of the scale you can not abstract at all and be able to tweak every little thing to get the best performance. Performance and abstraction in a general sense opposite's, so find somewhere in the middle that makes you happy.

In the case above i decided to make the method static then pass in either a user id, or an array. The code then checks if its an array or integer, if its an integer or if the array doesn't contain the required keys, it does a query lookup before generating a username for return.

That is where a Model View Controller framework can come in.

Basically every mysql table has a model each with its controller functions that use that models and different pages (or views) for that controller.


If you do not want to go the MVC route, i see no issue with making a User object class:

class User {
    public function __construct($ID){
          $user_query = "SELECT * FROM USERS WHERE id='$id'";
          //do the query
          //save all info to object:
          $this->username = $row['username'];
          $this->fname = $row['fname'];
          //...
    }

    public function getUserName(){
         return $this->username;
    }

    public function getFirstName(){
         return $this->fname;
    }

    //..etcetera
}

And you can use it like so:

$user = new User(1);

echo "Hello ".$user->getFirstName()." your username is: ".$user->getUserName();

In that particular situation I'd consider using a static method (http://www.php.net/manual/en/language.oop5.static.php). Something like this:

class User {

    /* all my normal class stuff to load a user */

    public static function getUsername($uid) {
        /* sql to retrieve username from db */
        return $username;
    }
}

$username = User::getUsername($uid);

In this way you avoid instantiating a new user object and just perform the necessary query.