Использование FQL для получения только предстоящих дней рождения из Facebook API - PullRequest
2 голосов
/ 04 ноября 2011

Используя информацию о FQL и пользовательской таблице из документации разработчика Facebook, я придумал следующий код.

    //build fql string
    $fql = "SELECT name, birthday_date FROM user 
              WHERE uid IN
                (SELECT uid2 FROM friend WHERE uid1 = me())
              AND strlen(birthday_date) != 0 AND substr(birthday_date,0,3) 
            IN ('{$currentMonth}/', '{$nextMonth}/')";
    $fql.=$orderBy;
    $fql.=" LIMIT " . $limit;

    //query facebook
    $params  =   array(
                 'method'    => 'fql.query',       
                 'query'     => $fql,
                 'callback'  => ''     
                  );
    $birthdays  =  $this->facebook_obj->api($params);

$currentMonth и $nextMonth устанавливаются на строковые представления текущего месяца и следующего месяца соответственно в формате мм.(например, «09», «10» и т. д.)

Это «работает», но давайте скажем, что сегодня 29 ноября, у меня 20 друзей с днем ​​рождения в ноябре, а $limit установлено на 10.В этом случае есть очень хороший шанс, что все 10 дней рождения, которые он возвращает, будут все до 29 ноября.

Что я действительно хотел бы сделать, так это получить ближайшие дни рождения с сегодняшнего дня, на этот месяц и на следующий,Как я могу изменить этот запрос, чтобы выполнить это?

Спасибо!

** Отредактируйте, см. Ветку комментариев между Шоном и мной для возможных альтернативных решений.Ответ пока не принят, поскольку ни один из них не имеет прямого отношения к исходному коду / вопросу.

Ответы [ 3 ]

9 голосов
/ 17 марта 2012

Это на несколько месяцев позже, но, возможно, помогает другим людям, сталкивающимся с той же проблемой. По сути, оператор FQL IN не проверяет, находится ли значение в заданном диапазоне, но соответствует ли данное значение любому из предоставленных различных значений. В вашем примере, если '09' и '10' являются значениями, тогда все дни рождения в сентябре и октябре возвращаются, так как эти дни рождения совпадают с предоставленными номерами месяцев.

Что вы можете сделать, это рассчитать следующие значения с использованием PHP или любого другого языка, который вы используете, и использовать их в своем FQL (сегодня 17 марта и говорят, что 17 апреля - дата окончания):

  • Сегодняшний день месяца (17),
  • Сегодняшний месяц года (03)
  • Дата окончания дня месяца (17)
  • Дата окончания месяца года (04)

Убедитесь, что дни и месяцы отформатированы с использованием дд и мм соответственно (с добавлением нуля в случае однозначных цифр). Тогда ваш FQL будет выглядеть так:

      SELECT name, birthday_date
      FROM user 
      WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me())
      AND strlen(birthday_date) != 0
      AND ((substr(birthday_date, 0, 2) = '03'
      AND substr(birthday_date, 3, 5) >= '17')
      OR (substr(birthday_date, 0, 2) = '04'
      AND substr(birthday_date, 3, 5) < '17'))
      ORDER BY birthday_date

Затем вернутся друзья, чей день рождения выпадает между 17 марта и 17 апреля.

1 голос
/ 04 ноября 2011
AND created_time > strtotime('now') AND created_time < $endofnext

см. Образцы @ http://www.php.net/manual/en/function.strtotime.php#97025

с использованием "сейчас" вернет текущее дневное время.


Эта функция вернет последний день следующего месяца, независимо от того,какой месяц это.

<?php 
/* $now can be set to any strtotime(), yesterday, last month, last year etc; */
$now = "now"; 
function EndOfNext($now){
    function lastDayOfMonth($month = '', $year = '') 
    { 
       if (empty($month)) { 
          $month = date('m'); 
       } 
       if (empty($year)) { 
          $year = date('Y'); 
       } 
       $result = strtotime("{$year}-{$month}-01"); 
       $result = strtotime('-1 second', strtotime('+1 month', $result)); 
       return date('m/d/y', $result); 
    } 
    function addRealMonth($timeStamp) 
    { 
        $tempMonth = date('m', $timeStamp); 
        $tempYear  = date('Y', $timeStamp); 
        if($tempMonth == "12") 
        { 
            $tempMonth = 1; 
            $tempYear++; 
        } 
        else 
            $tempMonth++; 

        $newDate = lastDayOfMonth($tempMonth, $tempYear); 
        return strtotime($newDate); 
    }
    $newChargeDate = strtotime($now); 
    $newChargeDate = addRealMonth($newChargeDate); 
    return date("m/d/y", $newChargeDate); 
}
$endofnext = EndOfNext($now);
echo $endofnext;
?>
0 голосов
/ 15 июня 2012

Вы также можете позволить FQL выполнить некоторую работу за вас, например:

SELECT uid, name, birthday_date, strtotime(substr(birthday_date, 0, 5)) > now()
FROM user
WHERE uid in (SELECT uid2 FROM #freunde)
AND birthday_date <> ''
AND strpos(birthday_date,'06') = 0
ORDER BY substr(birthday_date, 0, 5)

возвращает поле логического типа «anon», сообщающее, нужно ли включать этот результат в список отображения (true) или если день рождения этого пользователя уже в прошлом (false). К сожалению, я не смог заставить это предложение работать в качестве предложения WHERE - продолжаю понимать ошибку, но хотел бы знать, был ли кто-то более удачливым, чем я.

  "error": {
    "message": "Call to a member function on a non-object", 
    "type": "BadMethodCallException"
  }
...