3

我想知道这是否是解决此问题的最佳方法。我正在将 Facebook 用户的朋友数据(来自 facebook - 返回一个多数组)与该列表中投票的用户的投票(来自 MySQL)合并。

这就是我实现这一目标的方式。我是一名初级开发人员,正在寻求帮助以使我的代码尽可能优化。

public function getFriendVotes(){
    global $facebook;

    // Get The users friends that use this app from facebook
    $friends = $facebook->api_client->fql_query(
      "SELECT uid, first_name, last_name
        FROM user
        WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user)"
    );

    // Create an array of just the ids
    foreach($friends as $friend){
      $userids[] = $friend['uid'];
    }

    // Create a string of these ids
    $idstring = implode(",", $userids);

    // Get the votes from only the users in that list that voted
    $result = $this->db->query(
      "SELECT vote, userid FROM user_votes WHERE userid IN ($idstring)"
    );

    // Create a new result set (multi array).  Include the data from the first
    // Facebook query, but include only those who voted and append their votes
    // to the data
    $row = $result->fetch_assoc();
    foreach($friends as $friend){
      if($row['userid'] == $friend['uid']){
        $return[$count] = $friend;
        $return[$count]['vote'] = $row['vote'];
        $row = $result->fetch_assoc();
        $count++;
      }
    }
    return $return;
}
4

6 回答 6

2

我认为 fql_query 确实支持 mysql 语法,使用 LEFT JOIN 代替创建额外查询会更有效,这是我的代码版本:

public function getFriendVotes(){
    global $facebook;

    // Get The users friends that use this app from facebook
    $friends = $facebook->api_client->fql_query("
        SELECT DISTINCT u.uid,u.first_name,u.last_name 
        FROM user AS u 
        LEFT JOIN friend AS f ON uid=uid2 
        WHERE f.uid1='{$this->user}'
    ");
    $arrayUsers = array();
    // Create an array of just the ids
    foreach($friends as $v){
        $arrayUsers[$friend['uid']] = $v;
    }
    unset($friends);

    // Create a string of these ids
    $idstring = implode(",", array_keys($arrayUsers));

    // Get the votes from only the users in that list that voted
    $result = $this->db->query(
      "SELECT vote, userid FROM user_votes WHERE userid IN ({$idstring})"
    );

    $result = array();
    // Create a new result set (multi array).  Include the data from the first
    // Facebook query, but include only those who voted and append their votes
    // to the data
    while($v = $result->fetch_assoc())
    {
        if(isset($arrayUsers[$v['userid']])
        {

            $arrayUsers[$v['userid']] = $v['vote'];

            $result[] = $arrayUsers[$v['userid']];

            unset($arrayUsers[$v['userid']], $v);
        }
    }

    return $return;
}
于 2009-11-09T23:21:54.720 回答
2

如果不进行测量和测试,我无法告诉您代码的执行情况。我会寻找您的代码的其他问题,这将使其更具可读性/可维护性。例如:

创建更小的方法。

在 main 方法中,我看到了一些注释很好的代码块。为什么不创建一个方法而不是在 main 方法中进行大量注释呢?

例如:

// Get The users friends that use this app from facebook
$friends = $facebook->api_client->fql_query(
  "SELECT uid, first_name, last_name
    FROM user
    WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user"
);
return $friends;

会做一个有趣的

functin get_users_friends_from_facebook($facebook){
    // Get The users friends that use this app from facebook
    $friends = $facebook->api_client->fql_query(
      "SELECT uid, first_name, last_name
        FROM user
        WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user"
    );
    return $friends;
}

以相同的方式,

// Get the votes from only the users in that list that voted
$result = $this->db->query(
  "SELECT vote, userid FROM user_votes WHERE userid IN ($idstring)"
);

是一个很好的候选人

function get_votes_from_voters(){
    // Get the votes from only the users in that list that voted
    $votes = $this->db->query(
      "SELECT vote, userid FROM user_votes WHERE userid IN ($idstring)"
    );
}

为上下文赋予变量有意义的名称。

$return不是一个好名字。为什么不$users_votes举个例子呢?

尽量保持平台的命名约定。

检查您正在使用的 API。他们在使用camelCase吗?他们使用下划线吗?尽量遵守您的库和平台约定。检查此主题以获得良好的参考。

欢迎来到 SO。你的代码很好。尝试阅读一些 OO 原则,您甚至可以减少更多代码行。我在这里写的所有简单建议都可以在一本名为Code Complete的好书中找到。

于 2009-11-09T23:22:20.443 回答
2

我从您的所有评论中得分,并重写了这个方法,如下所示。感谢所有伟大的投入。

public function getAppUserFriends(){
    global $facebook;
    return $facebook->api_client->fql_query(
        "SELECT uid, first_name, last_name
        FROM user
        WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user)
        AND is_app_user;"
    );
}

public function getFriendVotes(){

    // Get the users friends that use this app
    $friends = $this->getAppUserFriends();

    // Create an array with the ids as the key
    foreach($friends as $v){
        $arrayFriends[$v['uid']] = $v;
    }

    // Create a string of these ids
    $idString = implode(",", array_keys($arrayFriends));

    // Get the votes from only the users in that list that voted
    $result = $this->db->query(
        "SELECT vote, userid
        FROM user_votes
        WHERE pollid=$this->poll
        AND userid IN ($idString)"
    );

    // Pluck out user data from facebook array where the user has voted
    // and add the vote to that array
    while($row = $result->fetch_assoc()){
        $friendsVotes[$row['userid']] = $arrayFriends[$row['userid']];
        $friendsVotes[$row['userid']]['vote'] = $row['vote'];
    }
    return $friendsVotes;
}
于 2009-11-10T09:28:21.180 回答
1

您是否在这种方法中遇到性能问题?因为除非你是,否则没有必要优化它。

首先编写代码,分析代码,然后优化它最擅长的地方。

于 2009-11-09T22:55:33.057 回答
0
$friends = $facebook->api_client->fql_query(
  "SELECT uid, first_name, last_name
    FROM user
    WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user"
);

可能会缩短为

$userids = $facebook->api_client->fql_query(
  "SELECT uid
    FROM user
    WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$this->user)"
);

因为 uid 是您似乎从 fb 使用的唯一东西

于 2009-11-10T04:27:01.490 回答
0

我很难说出您要做什么,但您可能会考虑查看 PHP array_intersect(及其表亲)。

A = {1:'fred', 2:'bob'}
B = {1: 2, 3: 0}

C = array_intersect( array_keys(A), array_keys(B) )
D = {}
foreach (C as c) {
  D[c] = (A[c], B[c])
}

语法在那里,但我希望它能引导你朝着正确的方向前进。

于 2009-11-10T04:27:15.667 回答