特定チャンネルの動画を視聴数順で取得し、ランキング表示する実装方法を解説します。今回は「直近3ヶ月以内に投稿された動画」に絞ったランキング取得を例にします。
事前準備
- Google Cloud Console でプロジェクトを作成
- YouTube Data API v3 を有効化
- 認証情報から APIキー を発行
- 対象チャンネルの チャンネルID を確認(チャンネルページのURL末尾など)
⚠️ APIキーは必ず環境変数や設定ファイルで管理し、ソースコードに直書きしないようにしましょう。
基本実装
<?php
// =============================
// 設定
// =============================
$DEVELOPER_KEY = getenv('YOUTUBE_API_KEY'); // 環境変数から取得を推奨
$CHANNEL_ID = 'UCxxxxxxxxxxxxxxxxxxxxxxx'; // 対象チャンネルID
$MAX_RESULTS = 5; // 取得件数(最大50)
$MONTHS_AGO = 3; // 何ヶ月前まで遡るか
// 期間の起点日時をISO 8601形式で生成
$PERIOD = date('Y-m-d', strtotime("-{$MONTHS_AGO} month")) . 'T00:00:00Z';
// =============================
// APIリクエスト
// =============================
$params = [
'type' => 'video',
'part' => 'snippet',
'maxResults' => $MAX_RESULTS,
'regionCode' => 'JP',
'channelId' => $CHANNEL_ID,
'order' => 'viewCount', // 視聴数順(他: date / rating / relevance)
'publishedAfter'=> $PERIOD,
'key' => $DEVELOPER_KEY,
];
$url = 'https://www.googleapis.com/youtube/v3/search?' . http_build_query($params);
$result = file_get_contents($url);
if ($result === false) {
die('APIリクエストに失敗しました。');
}
$result = json_decode($result, true);
if (isset($result['error'])) {
die('APIエラー: ' . $result['error']['message']);
}
// =============================
// データ整形
// =============================
$rankingList = [];
foreach ($result['items'] as $item) {
$rankingList[] = [
'videoId' => $item['id']['videoId'],
'title' => $item['snippet']['title'],
'description' => $item['snippet']['description'],
'thumbnail_medium' => $item['snippet']['thumbnails']['medium']['url'],
'publishedAt' => $item['snippet']['publishedAt'],
'channelTitle' => $item['snippet']['channelTitle'],
];
}PHP
http_build_query()を使うと、配列から安全にURLクエリ文字列を生成できます(特殊文字の自動エスケープつき)。
HTML出力
// =============================
// 出力
// =============================
?>
<ol class="ranking-list">
<?php foreach ($rankingList as $rank => $video): ?>
<li class="ranking-item">
<span class="rank-number"><?= $rank + 1 ?></span>
<a href="https://www.youtube.com/watch?v=<?= htmlspecialchars($video['videoId']) ?>" target="_blank">
<img src="<?= htmlspecialchars($video['thumbnail_medium']) ?>"
alt="<?= htmlspecialchars($video['title']) ?>">
<div class="video-info">
<h3><?= htmlspecialchars($video['title']) ?></h3>
<p class="published"><?= date('Y年m月d日', strtotime($video['publishedAt'])) ?></p>
<p class="description"><?= htmlspecialchars(mb_substr($video['description'], 0, 80)) ?>...</p>
</div>
</a>
</li>
<?php endforeach; ?>
</ol>PHP
htmlspecialchars()で出力時のXSS対策を忘れずに。
視聴数も取得したい場合(videos.list の併用)
search.list のレスポンスには実際の視聴数が含まれません。視聴数を表示したい場合は、取得したビデオIDを使って videos.list を追加で呼び出す必要があります。
// videoIdをカンマ区切りで結合
$videoIds = implode(',', array_column($rankingList, 'videoId'));
$statsParams = [
'part' => 'statistics',
'id' => $videoIds,
'key' => $DEVELOPER_KEY,
];
$statsUrl = 'https://www.googleapis.com/youtube/v3/videos?' . http_build_query($statsParams);
$statsResult = json_decode(file_get_contents($statsUrl), true);
// rankingListに視聴数をマージ
$statsMap = [];
foreach ($statsResult['items'] as $item) {
$statsMap[$item['id']] = $item['statistics']['viewCount'];
}
foreach ($rankingList as &$video) {
$video['viewCount'] = $statsMap[$video['videoId']] ?? 0;
}
unset($video);PHPこれで $video['viewCount'] に視聴数が入ります。
応用:キャッシュで API クォータを節約する
YouTube Data API v3 には**1日あたりのクォータ制限(デフォルト10,000ユニット)**があります。毎回APIを叩くのではなく、結果をファイルやDBにキャッシュしておくのがベストプラクティスです。
$cacheFile = __DIR__ . '/cache/youtube_ranking.json';
$cacheExpiry = 3600; // 1時間キャッシュ
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < $cacheExpiry)) {
// キャッシュから読み込み
$rankingList = json_decode(file_get_contents($cacheFile), true);
} else {
// APIから取得(上記コード)
// ...
// キャッシュに保存
file_put_contents($cacheFile, json_encode($rankingList));
}PHPよくあるエラーと対処法
| エラー内容 | 原因 | 対処 |
|---|---|---|
keyInvalid | APIキーが誤っている | Cloud ConsoleでAPIキーを確認 |
quotaExceeded | 1日のクォータ超過 | キャッシュ導入、または翌日まで待つ |
forbidden | APIが有効化されていない | YouTube Data API v3 を有効化 |
| 結果が0件 | チャンネルIDの誤り・対象期間に動画なし | チャンネルIDを再確認 |
まとめ
order=viewCount+publishedAfterで期間絞り込みランキングが取得できる- 実際の視聴数表示は
videos.listとの2段階取得が必要 - APIキーは環境変数管理 & 結果はキャッシュでクォータを節約
- 出力時は必ず
htmlspecialchars()でXSS対策を行う