PHP 函数中的递归函数:如何防止 return 值?
Recursive function in PHP function : how to prevent return value?
我正在研究 API 来获取数据,就像其他标准 API 一样,它限制了项目的 return 数量,例如在我的案例中,每页 return 只有 1 项。所以,我必须得到
- total_count、
- page_size(我的情况是 1),
- 和current_page_number.
问题是,无论我将它设置为递归,它仍然return第一个循环的值。例如如果总共有 3 个项目,并且每页限制为 1 个项目,它将 return 第一次循环中的值。
为什么以及如何解决这个问题?
非常感谢
function get_video_list($page_no = 0, $filter_video = array()) {
$api = "http://api.brightcove.com/services/library?command=search_videos&page_size=1&video_fields=id%2Cname%2CcreationDate%2CFLVURL%2CpublishedDate%2ClinkURL%2CthumbnailURL%2Clength&media_delivery=http&sort_by=CREATION_DATE%3AASC&page_number=$page_no&get_item_count=true&token=" . READ_TOKEN;
try {
$ch = curl_init();
if (FALSE === $ch) {
throw new Exception('failed to initialize');
}
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
if (FALSE === $content) {
throw new Exception(curl_error($ch), curl_errno($ch));
}
$video_list = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
$page_number = ($video_list->page_number) + 1; //start at 0
$page_size = $video_list->page_size;
$total_count = $video_list->total_count;
foreach ($video_list->items as $video) {
if (in_array($video->id, $stored_video)) {
$filter_video [] = $video;
}
}
if ($total_count > $page_size * $page_number) {
get_video_list($page_number, $filter_video);
}
return $filter_video;
} catch (Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}
}
这应该可以解决您的问题。
if ($total_count > $page_size * $page_number) {
return get_video_list($page_number, $filter_video);
}
您没有将递归回调的 return 值分配给 $filter_video,更改为:
if ($total_count > $page_size * $page_number) {
$filter_video = get_video_list($page_number, $filter_video);
}
或者,甚至更好:通过引用传递。这完全消除了对 return 值的需要,这对递归函数特别有用(注意函数声明中的 &$filter_video,参见 http://php.net/manual/en/language.references.pass.php)。
function get_video_list($page_no = 0, &$filter_video = array()) {
$api = "http://api.brightcove.com/services/library?command=search_videos&page_size=1&video_fields=id%2Cname%2CcreationDate%2CFLVURL%2CpublishedDate%2ClinkURL%2CthumbnailURL%2Clength&media_delivery=http&sort_by=CREATION_DATE%3AASC&page_number=$page_no&get_item_count=true&token=" . READ_TOKEN;
try {
$ch = curl_init();
if (FALSE === $ch) {
throw new Exception('failed to initialize');
}
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
if (FALSE === $content) {
throw new Exception(curl_error($ch), curl_errno($ch));
}
$video_list = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
$page_number = ($video_list->page_number) + 1; //start at 0
$page_size = $video_list->page_size;
$total_count = $video_list->total_count;
foreach ($video_list->items as $video) {
if (in_array($video->id, $stored_video)) {
$filter_video [] = $video;
}
}
if ($total_count > $page_size * $page_number) {
get_video_list($page_number, $filter_video);
}
} catch (Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}
}
然后这样称呼它:
$myVideoList = [];
get_video_list(0, $myVideoList);
// Do stuff with $myVideoList
我正在研究 API 来获取数据,就像其他标准 API 一样,它限制了项目的 return 数量,例如在我的案例中,每页 return 只有 1 项。所以,我必须得到
- total_count、
- page_size(我的情况是 1),
- 和current_page_number.
问题是,无论我将它设置为递归,它仍然return第一个循环的值。例如如果总共有 3 个项目,并且每页限制为 1 个项目,它将 return 第一次循环中的值。
为什么以及如何解决这个问题?
非常感谢
function get_video_list($page_no = 0, $filter_video = array()) {
$api = "http://api.brightcove.com/services/library?command=search_videos&page_size=1&video_fields=id%2Cname%2CcreationDate%2CFLVURL%2CpublishedDate%2ClinkURL%2CthumbnailURL%2Clength&media_delivery=http&sort_by=CREATION_DATE%3AASC&page_number=$page_no&get_item_count=true&token=" . READ_TOKEN;
try {
$ch = curl_init();
if (FALSE === $ch) {
throw new Exception('failed to initialize');
}
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
if (FALSE === $content) {
throw new Exception(curl_error($ch), curl_errno($ch));
}
$video_list = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
$page_number = ($video_list->page_number) + 1; //start at 0
$page_size = $video_list->page_size;
$total_count = $video_list->total_count;
foreach ($video_list->items as $video) {
if (in_array($video->id, $stored_video)) {
$filter_video [] = $video;
}
}
if ($total_count > $page_size * $page_number) {
get_video_list($page_number, $filter_video);
}
return $filter_video;
} catch (Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}
}
这应该可以解决您的问题。
if ($total_count > $page_size * $page_number) {
return get_video_list($page_number, $filter_video);
}
您没有将递归回调的 return 值分配给 $filter_video,更改为:
if ($total_count > $page_size * $page_number) {
$filter_video = get_video_list($page_number, $filter_video);
}
或者,甚至更好:通过引用传递。这完全消除了对 return 值的需要,这对递归函数特别有用(注意函数声明中的 &$filter_video,参见 http://php.net/manual/en/language.references.pass.php)。
function get_video_list($page_no = 0, &$filter_video = array()) {
$api = "http://api.brightcove.com/services/library?command=search_videos&page_size=1&video_fields=id%2Cname%2CcreationDate%2CFLVURL%2CpublishedDate%2ClinkURL%2CthumbnailURL%2Clength&media_delivery=http&sort_by=CREATION_DATE%3AASC&page_number=$page_no&get_item_count=true&token=" . READ_TOKEN;
try {
$ch = curl_init();
if (FALSE === $ch) {
throw new Exception('failed to initialize');
}
curl_setopt($ch, CURLOPT_URL, $api);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
if (FALSE === $content) {
throw new Exception(curl_error($ch), curl_errno($ch));
}
$video_list = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
$page_number = ($video_list->page_number) + 1; //start at 0
$page_size = $video_list->page_size;
$total_count = $video_list->total_count;
foreach ($video_list->items as $video) {
if (in_array($video->id, $stored_video)) {
$filter_video [] = $video;
}
}
if ($total_count > $page_size * $page_number) {
get_video_list($page_number, $filter_video);
}
} catch (Exception $e) {
trigger_error(sprintf('Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR);
}
}
然后这样称呼它:
$myVideoList = [];
get_video_list(0, $myVideoList);
// Do stuff with $myVideoList