Pregunta

Me pregunto si esta es la mejor manera de abordar esta cuestión. Estoy Fusionar una de Facebook los usuarios datos de amigos, (desde el facebook - devuelve una matriz multi) con los votos de los usuarios en esa lista que votaron (de MySQL).

Esta es la forma en que he logrado esto. Soy un desarrollador junior y en busca de ayuda en hacer mi código optimizado como sea posible.

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;
}
¿Fue útil?

Solución

Asumo que fql_query hace sintaxis soporte para MySQL y sería más eficaz utilizar LEFT JOIN en lugar creatig consulta adicional, aquí está mi versión de su código:

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

Otros consejos

No puedo decir cómo su código llevaría a cabo sin la medición y prueba. Me gustaría ver a otros problemas con su código, que harían un poco más legible / maintanable. Por ejemplo:

Crear métodos más pequeñas.

Dentro del método principal, veo algunos trozos de código que están bien comentado. ¿Por qué no crear un método en vez de hacer un gran comentario en el método principal?

Por ejemplo:

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

Haría una interesante

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 misma manera,

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

Es un buen candidato a

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

Dar a las variables nombres significativos con el contexto.

$return no es un buen nombre. ¿Por qué no se lo nombra $users_votes por ejemplo?

Trate de mantener la convención de nomenclatura de su plataforma.

Comprobar la API que está utilizando. Están utilizando camelCase? Están utilizando guiones? Trate de mantener con sus bibliotecas y convenciones plataform. Compruebe este tema para una buena referencia.

Y la bienvenida a SO. Su código está muy bien. Intenta leer algunos principios OO, incluso se podría cortar más líneas de código. Todos los consejos simples que escribieron aquí están disponibles en un gran libro llamado código completo .

Me quitó puntos a todos sus comentarios y volvió a escribir este método como a continuación. Gracias a todos por la gran entrada.

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

¿Está teniendo problemas de rendimiento en este método? Porque a menos que se encuentre, no hay necesidad para optimizarlo.

Código primera, perfil del código, y luego optimizar donde se hace el mayor 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"
);

probablemente podría ser acortado a

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

debido a que el fluido es el único que parece estar utilizando desde fb

Fue un poco difícil para mí decir lo que está tratando de hacer, pero es posible considerar la búsqueda de array_intersect de PHP (y sus primos).

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 sintaxis es fuera allí, pero espero que se lleva en la dirección correcta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top