Объединение данных из двух разных наборов данных (Facebook и MySQL)
-
19-09-2019 - |
Вопрос
Мне интересно, является ли это лучшим способом решения этой проблемы.Я объединяю данные друзей пользователей 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;
}
Решение
Я предполагаю, что 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;
}
Другие советы
Я не могу сказать вам, как будет работать ваш код без измерений и испытаний.Я бы поискал другие проблемы в вашем коде, которые сделали бы его более читабельным/обслуживаемым.Например:
Создавайте меньшие методы.
Внутри основного метода я вижу несколько фрагментов кода, которые хорошо прокомментированы.Почему бы не создать метод вместо того, чтобы делать огромный комментарий в основном методе?
Например:
// 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?Используют ли они подчеркивания?Постарайтесь придерживаться соглашений о ваших библиотеках и платформах.Проверять Эта тема за хорошую ссылку.
И добро пожаловать в ТАК.Ваш код в порядке.Попробуйте прочитать некоторые принципы объектно-ориентированного программирования, вы можете даже сократить больше строк своего кода.Все простые советы, которые я здесь написал, доступны в замечательной книге под названием Код завершен.
Я взял моменты из всех ваших комментариев и переписал этот метод, как показано ниже.Спасибо за отличный вклад.
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;
}
У вас проблемы с производительностью в этом методе?Потому что, если вы этого не сделаете, нет необходимости оптимизировать его.
Сначала напишите код, профилируйте его, а затем оптимизируйте там, где он приносит наибольшую пользу.
$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 - это единственное, что ты, кажется, используешь с Facebook
Мне было немного сложно сказать, что вы пытаетесь сделать, но вы могли бы рассмотреть возможность просмотра 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])
}
Синтаксис здесь неверен, но я надеюсь, что он приведет вас в правильном направлении.