La fusion de données provenant de deux ensembles de données différentes (Facebook & MySQL)

StackOverflow https://stackoverflow.com/questions/1704137

Question

Je me demande si cela est la meilleure façon d'aborder cette question. Je suis un utilisateur Facebook fusionnez amis données, (de facebook - renvoie un tableau multi) avec les votes des utilisateurs dans cette liste qui ont voté (de MySQL).

Voilà comment j'accompli cela. Je suis un développeur junior et chercher de l'aide à rendre mon code aussi optimisée possible.

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;
}
Était-ce utile?

La solution

Je suppose que fql_query ne syntaxe le support MySQL, et il serait plus efficace d'utiliser LEFT JOIN à la place creatig requête supplémentaire, voici ma version de votre code:

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;
}

Autres conseils

Je ne peux pas vous dire comment votre code exécuterait sans mesure et de contrôle. Je chercherais d'autres problèmes avec votre code, qui rendrait un peu plus lisible / maintanable. Par exemple:

Créer de plus des méthodes.

Dans la méthode principale, je vois quelques morceaux de code qui sont bien commentés. Pourquoi ne pas créer une méthode au lieu de faire un énorme commentaire dans la principale méthode?

Par exemple:

// 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;

Ferait un intéressant

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;
}

De la même manière,

// 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)"
);

est un bon candidat à

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)"
    );
}

Donner des variables des noms significatifs au contexte.

$return n'est pas un bon nom. Pourquoi ne vous nommez pas $users_votes par exemple?

Essayez de garder la convention de nommage de votre plataform.

Vérifiez la apis que vous utilisez. Est-ce qu'ils utilisent camelCase? Sont-ils utilisent underscores? Essayez de garder vos bibliothèques et conventions de Plataform. Consultez ce sujet pour une bonne référence.

Et bienvenue à SO. Votre code est très bien. Essayez de lire certains principes OO, vous pouvez même couper plusieurs lignes de votre code. Tous les conseils simples, j'ai écrit ici sont avaiable dans un livre intitulé code complet .

J'ai pris des points de tous vos commentaires et récrit cette méthode comme ci-dessous. Merci pour la grande entrée.

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;
}

Avez-vous des problèmes de performance dans cette méthode? Parce que si vous n'êtes pas, il n'y a pas besoin de l'optimiser.

code d'abord, le profil le code, puis optimiser où il fait le plus grand bien.

$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"
);

pourrait probablement être raccourci à

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

parce que l'uid est la seule chose que vous semblez être en utilisant de fb

Il était un peu difficile pour moi de dire ce que vous essayez de faire, mais vous pourriez envisager de regarder la array_intersect de PHP (et ses cousines).

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])
}

La syntaxe est hors là, mais j'espère que cela vous mène dans la bonne direction.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top