合并来自两个不同数据集的数据(Facebook和MySQL)

时间:2009-11-09 21:53:49

标签: php mysql facebook facebook-fql

我想知道这是否是解决此问题的最佳方法。我正在合并一个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;
}

6 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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吗?他们使用下划线吗?尽量保持你的库和plataform约定。检查this topic以获得一个很好的参考。

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

答案 2 :(得分: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;
}

答案 3 :(得分:1)

这种方法是否存在性能问题?因为除非你,否则没有必要对它进行优化。

首先编码代码,对代码进行概要分析,然后优化代码的最佳位置。

答案 4 :(得分: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

的东西

答案 5 :(得分: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])
}

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