You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

file_get_contents()调用YouTube API时灵时不灵?API配额耗尽求解

解决YouTube API调用稳定性与配额耗尽问题

Hey there, let's break down your two issues and fix up that code along the way!


1. 稳定调用file_get_contents获取YouTube频道信息

First off, the most obvious issue in your code is a typo: file_get_contents_url isn't a built-in PHP function—you meant file_get_contents! That mistake alone is causing random failures. Beyond that, here are key improvements to make calls more reliable:

  • Add HTTP context configuration

YouTube may block requests without a proper User-Agent, or time out if no limit is set. Add context settings to file_get_contents:

$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
        'timeout' => 10 // 10-second timeout to avoid hanging
    ]
]);
$extractInfo = file_get_contents($channelInfo, false, $context);
  • Add error handling & retry logic

file_get_contents returns false on failure, so add checks and a simple retry loop to handle temporary glitches:

$maxRetries = 3;
$retryCount = 0;
$extractInfo = false;

while ($retryCount < $maxRetries && $extractInfo === false) {
    $extractInfo = file_get_contents($channelInfo, false, $context);
    $retryCount++;
    if ($extractInfo === false) sleep(1); // Short delay before retrying
}

if ($extractInfo === false) {
    die("Failed to fetch channel info after $maxRetries attempts");
}
  • Switch to cURL for more control

If file_get_contents still acts flaky, cURL offers better visibility into HTTP errors and more granular settings:

$ch = curl_init($channelInfo);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36');
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$extractInfo = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($extractInfo === false || $httpCode >= 400) {
    die("Request failed with HTTP code: $httpCode");
}
curl_close($ch);

2. Why your API quota is draining so fast

This is a common pitfall with YouTube Data API v3, and there are two core reasons:

  • High quota cost of the search.list endpoint

YouTube's API uses quota units per request, and the search.list endpoint you're using costs 100 units per call! The free tier only gives you 10,000 units per day—so 50 refreshes eat up 5000 units, half your daily quota.

  • No caching mechanism

Your code makes a fresh API request every time someone refreshes the page, even if the channel's live status hasn't changed. Multiple users or frequent testing will burn through quota in no time.

Fixes for quota exhaustion:

  • Use more efficient API endpoints: Instead of search.list, use channels.list (1 unit) to get the channel's uploads playlist, then playlistItems.list (1 unit) to check for live content—way cheaper than 100 units per call.
  • Add server-side caching: Store API results in a file, database, or Redis for 5–10 minutes, so you only re-request when the cache expires:
$cacheFile = 'youtube_live_cache.json';
$cacheExpiry = 300; // 5 minutes in seconds

if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $cacheExpiry) {
    $extractInfo = file_get_contents($cacheFile);
} else {
    // Make your API request here
    file_put_contents($cacheFile, $extractInfo); // Save to cache
}
  • Restrict your API key: In the Google Cloud Console, set IP restrictions on your key so only your server can use it—prevents unauthorized use from draining your quota.

Revised Full Code

Here's your code with all fixes and improvements integrated:

<?php
header("Access-Control-Allow-Origin: *");
error_reporting(~0);
ini_set('display_errors', 1);

$API_KEY = 'API KEY HERE';
$ChannelID = 'CHANNEL ID HERE';
$cacheFile = 'youtube_live_cache.json';
$cacheExpiry = 300; // 5-minute cache

// Use cached data if available and fresh
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $cacheExpiry) {
    $extractInfo = file_get_contents($cacheFile);
} else {
    $channelInfo = "https://www.googleapis.com/youtube/v3/search?part=snippet&channelId={$ChannelID}&type=video&eventType=live&key={$API_KEY}";
    $ch = curl_init($channelInfo);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36');
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    $extractInfo = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if ($extractInfo === false || $httpCode >= 400) {
        die("Failed to fetch channel info (HTTP {$httpCode})");
    }
    curl_close($ch);

    // Save response to cache
    file_put_contents($cacheFile, $extractInfo);
}

// Parse JSON and validate
$showInfo = json_decode($extractInfo, true);
if (json_last_error() !== JSON_ERROR_NONE) {
    die("Invalid JSON response from YouTube");
}

// Check live status
if ($showInfo['pageInfo']['totalResults'] === 0) {
    echo 'Users channel is Offline';
} else {
    echo 'Users channel is LIVE!';
}

// Extract video ID safely
$videoId = '';
if (!empty($showInfo['items'])) {
    $videoId = $showInfo['items'][0]['id']['videoId'];
}

if (empty($videoId)) {
    echo "<h2>No live stream yet.</h2>";
} else {
    echo "<h2>{$videoId}</h2>";
}
?>

内容的提问来源于stack exchange,提问作者michelangelo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:37:47