可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Using the information on FQL and the user table from Facebook's Developer's docs, I've come up with the following code.
//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
and $nextMonth
are set to string representations of the current month and next month respectively, in mm format. (eg "09", "10" etc.)
This is "working", but let's say that today is November 29th, I have 20 friends with birthday's in November and $limit
is set to 10. In this case, there is a very good chance that the 10 birthdays it returns will all be before November 29th.
What I would really like to do is get upcoming birthdays from today's day out, for this month and next. How could I modify this query to accomplish that?
Thanks!
** Edit, see comment thread between Shawn and I for possible alternative solutions. No answer accepted yet as none directly addresses original code / question.
回答1:
This is some months late but maybe helps other people facing the same problem. Basically, the FQL IN
operator does not check whether the value is in a given range, but whether the given value matches any of the distinct values that are provided. In your example if '09' and '10' are the values, then all birthdays in September and October are returned since those birthday months match the provided month numbers.
What you can do is calculate the following values using PHP or whatever other language you are using and use them in your FQL (today is 17 March and say we want 17 April is end date):
- Today's day of the month (17),
- Today's month of the year (03)
- End date day of the month (17)
- End date month of the year (04)
Make sure days and months are formatted using dd and MM respectively (padded with zero in case of single digits). Then your FQL would look like this:
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
This will then return the friends who's birthday falls between 17 March and 17 April.
回答2:
AND created_time > strtotime('now') AND created_time < $endofnext
refer to samples @ http://www.php.net/manual/en/function.strtotime.php#97025
using "now" would return the current daytime.
This function will return the last day of next month no matter what month it is.
<?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;
?>
回答3:
You can also let FQL do some job for you, like in the following:
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)
returning a boolean type "anon" field telling if you have to include this result in the display list (true) or if the birthday for this user lies already in the past (false).
Unfortunately I wasn't able to have this proposition work as a WHERE clause - keep getting the error under, but would love to know if someone was luckier than I.
"error": {
"message": "Call to a member function on a non-object",
"type": "BadMethodCallException"
}