Help us understand the problem. What is going on with this article?

PHPでYoutubeのAPIを利用したい

この記事ですること

この記事では私のようなPHP初心者がYouYubeのAPIを使った様子を紹介致します。
PHPはもちろん、プログラミングスキルも低いです。初心者が初心者なりに頑張った様子を皆さまに見ていただきたいです。よろしくお願いいたします。

ちなみに開発環境ですが、

OS == Windows10
PHP == 7.4.11
Composer == 2.0.6

です。

YouTube Data API

YouTube Data APIはYouTubeとデータのやり取りをするため、デペロッパーを対象に提供されているサービスです。Googleアカウントを持っている人であれば気軽に使用できるAPIです。

YouTube Data APIでやりたいこと

私はこのYouTube Data APIで下記のことをやってみたいと考えました。

1.フォームからキーワード検索を行う
2.検索結果を取得する(YouTubeのようにサムネ、タイトル、概要など)
3.取得した検索結果を使用してみる。

実装

まず最初に...

phpを実行する場所(ディレクトリ)を作成します。
私はXAMPPを使っているので
xampp/htdocsに新しく「youtube_api」というディレクトリを作成します

C:\xampp\htdocs>mkdir youtube_api 

YouTube Data APIを使うために「Google APIs Client Library for PHP」が必要です。まずはこれをComposerでインストールします。

*Composerをインストールしていない方はこちらへ

Composerのインストール、コマンドプロンプトで動くことを確認できたら先ほど作成したディレクトリ内で下記のコマンドを打ちこみます。

composer require google/apiclient:"^2.7"

すると
vendor(ディレクトリ)
composer.json(ファイル)
composer.lock(ファイル)

というファイルが追加されます。
そして、ディレクトリ構造は以下のようになります。

youtube_api
|
+-----vendor
|       |
|       +-----諸々のファイル
|
|
+-----composer.json
|
+-----composer.lock
|
+-----sample.php

vendorディレクトリにあるautoload.phpをソースコードに取り込んでいきます。

APIキーを手に入れる


つぎにソースコードで実際にYouTube Data APIを使用するために必要な「APIコード」を手に入れます。
APIキーはGoogleアカウントをお持ちの方であれば手に入れることができます。
今回使うAPIのキーの手に入れ方を詳しく説明してくれる記事がすでに存在します。


[PHP]YouTube APIの利用(動画情報の取得) 筆者: @kuzira_vimmer さん


図を用いて非常にわかりやすく説明してあります。ぜひご参考にしてください。(私も参考にさせていただきました。)

まずはサンプルコードから

先ほど紹介させていただいた記事にも記載されていますが、PHPでYouTube Data API v3を使うサンプルコードが公式に用意されています。まずはこれを実行し、理解していきました。

ディレクトリ「youtube_api」内にsample.phpという名前のファイルを作成し、コピーします。

sample.php
<?php

/**
 * Library Requirements
 *
 * 1. Install composer (https://getcomposer.org)
 * 2. On the command line, change to this directory (api-samples/php)
 * 3. Require the google/apiclient library
 *    $ composer require google/apiclient:~2.0
 */
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
  throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}

require_once __DIR__ . '/vendor/autoload.php';

$htmlBody = <<<END
<form method="GET">
  <div>
    Search Term: <input type="search" id="q" name="q" placeholder="Enter Search Term">
  </div>
  <div>
    Max Results: <input type="number" id="maxResults" name="maxResults" min="1" max="50" step="1" value="25">
  </div>
  <input type="submit" value="Search">
</form>
END;

// This code will execute if the user entered a search query in the form
// and submitted the form. Otherwise, the page displays the form above.
if (isset($_GET['q']) && isset($_GET['maxResults'])) {
  /*
   * Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
   * Google API Console <https://console.developers.google.com/>
   * Please ensure that you have enabled the YouTube Data API for your project.
   */
  $DEVELOPER_KEY = 'REPLACE_ME';

  $client = new Google_Client();
  $client->setDeveloperKey($DEVELOPER_KEY);

  // Define an object that will be used to make all API requests.
  $youtube = new Google_Service_YouTube($client);

  $htmlBody = '';
  try {

    // Call the search.list method to retrieve results matching the specified
    // query term.
    $searchResponse = $youtube->search->listSearch('id,snippet', array(
      'q' => $_GET['q'],
      'maxResults' => $_GET['maxResults'],
    ));

    $videos = '';
    $channels = '';
    $playlists = '';

    // Add each result to the appropriate list, and then display the lists of
    // matching videos, channels, and playlists.
    foreach ($searchResponse['items'] as $searchResult) {
      switch ($searchResult['id']['kind']) {
        case 'youtube#video':
          $videos .= sprintf('<li>%s (%s)</li>',
              $searchResult['snippet']['title'], $searchResult['id']['videoId']);
          break;
        case 'youtube#channel':
          $channels .= sprintf('<li>%s (%s)</li>',
              $searchResult['snippet']['title'], $searchResult['id']['channelId']);
          break;
        case 'youtube#playlist':
          $playlists .= sprintf('<li>%s (%s)</li>',
              $searchResult['snippet']['title'], $searchResult['id']['playlistId']);
          break;
      }
    }

    $htmlBody .= <<<END
    <h3>Videos</h3>
    <ul>$videos</ul>
    <h3>Channels</h3>
    <ul>$channels</ul>
    <h3>Playlists</h3>
    <ul>$playlists</ul>
END;
  } catch (Google_Service_Exception $e) {
    $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
      htmlspecialchars($e->getMessage()));
  } catch (Google_Exception $e) {
    $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
      htmlspecialchars($e->getMessage()));
  }
}
?>

<!doctype html>
<html>
  <head>
    <title>YouTube Search</title>
  </head>
  <body>
    <?=$htmlBody?>
  </body>
</html>

このサンプルコード内にある $DEVELOPER_KEY = 'REPLACE_ME';というコードの 'REPLACE_ME'の部分を先ほど手に入れたAPIキーに変更します。

ここで補足情報ですが、APIキーやアクセストークンは基本、他人に知られてはいけません。

ですので環境変数でAPIキーを設定し、使うようにしましょう

環境変数をセットするためにWindowsの方はコマンドプロンプトで「set」コマンドを使いましょうAPIキーを格納する環境変数は「API_KEY」という名前にします

C:\xampp\htdocs\youtube_api>set API_KEY=自分のAPIキー

またsample.phpないの37行目にある $DEVELOPER_KEY = 'REPLACE_ME';も書き換えていきます。

PHPにあるライブラリ getenv()を使用して変数DEVELOPER_KEYに環境変数で設定したAPI_KEYを格納します

$DEVELOPER_KEY = getenv('API_KEY');

これでサンプルコードを動かす準備ができました。動かしてみましょう

*注意
私のXAMPP環境で実行したところAPIキーが上手く機能せず、認証エラーになりました。
そこで、コマンドラインからコマンドでプログラムを実行したところ正常に動きました。

作成したディレクトリ内で下記のコマンドを入力し、http://localhost:8080/sample.phpにアクセスしてください

php -S 127.0.0.1:8080

これでしっかりプログラムが動くと思います。

サンプルコードを簡単に読み解く

ではこのサンプルコードからどのような動きをしているのか、また公式ドキュメントからどんな情報が取得可能なのか把握していきます。

まず最初にサンプルコード17行目、78行目にある「$htmlBody」ですが、これはブラウザでHTMLを表示するための部分です。 ヒアドキュメントと言います。ヒアドキュメントを使うことで長い文字列を扱うことができます。
また、$htmlbodyが二つあるのは検索フォームを表示する時、YouTube Data APIで動画を検索した時の2パターンを作るためです。



次にAPIを使用するための認証、承認です。(サンプルコード39,40行目)

$client = new Google_Client(); //39行目
$client->setDeveloperKey($DEVELOPER_KEY); //40行目

$youtube = new Google_Service_YouTube($client);  //43行目

39行目でGoogle_Clientをインスタンス化,40行目で自身のAPIキーを使ってGoogleの提供しているAPIの使用を可能にします。
43行目のコードはYouTube Data APIのリクエストを行う変数を定義します。今後APIに対してリクエストを行う時はこの変数$youtubeを使います。

APIに実際にリクエストを行うためのパラメータ入力、検索結果の格納は50~53行目にあります。

$searchResponse = $youtube->search->listSearch('id,snippet', array(
      'q' => $_GET['q'],
      'maxResults' => $_GET['maxResults'],
    ));

このコードによってフォームの「q」,「maxResults」を受け取り、API機能のひとつ「search」の中に存在する「listSearch」にフォームから受け取った情報をパラメータとして代入、$searchResponseに検索結果を格納できます。

変数「searchResponse」はキーワードを検索したときに表示される動画を上からかぞえて$maxResult個取得します。

ここまで理解できれば、あとは検索結果がどんなプロパティを所持しているのか確認することで様々なデータを取得、表示することができます。

*ちなみにlistSearchによって検索結果が複数取得できます。
そのため出力方法がfor文での出力になっています。

YouTube Data API searchで取得できるデータ

これから話すことは全て公式ドキュメントに記述されています。

公式のページを閲覧したいかたはこちらへ(YouTube Data API Search)
もう1つご紹介させていただきます。こちら(YouTube Data API Search:list)
私の記事と同時進行で読んでいただけると記事の理解が深まると思います。

サンプルコードでは以下の3つのプロパティが登場しています。

$searchResult['snippet']['title'] // -> 検索結果のタイトル
$searchResult['id']['videoId'] // -> 動画のクエリ("https://www.youtube.com/watch?v="ここに入る文字列)
$searchResult['id']['channelId'] // -> 検索ワードに合致するチャンネルID("https://www.youtube.com/channel/"ここに入る文字列)
$searchResult['id']['playlistId'] // -> プレイリストを開いた時,URL: "https://www.youtube.com/watch?v="動画のクエリ"&list=ここに入る文字列"

確認も兼ねてテストをします。
「キーワード=櫻坂46」、「動画取得数=10」でAPIから情報を収集してみます。
youtubeDataAPI(テスト).PNG

ソースコード内ではcase文であらかじめ取得データが動画なのか、チャンネル名なのかチェックしています。
プレイリストは見つかりませんでしたが、動画タイトル、動画ID、チャンネル名、チャンネルIDの取得ができました。

他にもたくさんのデータが取得可能です。ドキュメントは日本語版もありますので是非参考にしてください。

YouTube Data APIで動画情報を取得し、色々表示させてみる

駆け足ですが、かんたんな構造が理解でき、どんな情報を取得できるのかわかってきましたので少しコードを書き替えていきます。

まず最初に自分がYouTube Data APIを使ってやってみたいことを列挙してみます。


  1. 表示するものを動画とチャンネルのみに絞る

  2. サムネの表示

  3. チャンネルの画像表示

  4. サムネをクリックすると動画リンクへ移動する

  5. 動画の投稿者を特定する

  6. 動画投稿者のチャンネルへ移動する

  7. 動画,チャンネルに番号を振ってしっかり検索ができているのか確認できるようにする

上記の機能を持つプログラムを実装していきます。
また、実現にあたって1度紹介させていただいたリンクを今一度共有させていただきます。
YouTube Data APIのメソッド,プロパティ一覧(公式)

完成したコードがこちらになります。コメントも書いてありますが、わかりずらい可能性が高いです。

<?php

if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
  throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}

require_once __DIR__ . '/vendor/autoload.php';

//検索ワードが入っていないときに表示されるHTML
$htmlBody = <<<END
<form method="GET">
  <div>
    Search Term: <input type="search" id="q" name="q" placeholder="Enter Search Term">
  </div>
  <div>
    Max Results: <input type="number" id="maxResults" name="maxResults" min="1" max="50" step="1" value="25">
  </div>
  <input type="submit" value="Search">
</form>
END;

// This code will execute if the user entered a search query in the form
// and submitted the form. Otherwise, the page displays the form above.
if (isset($_GET['q']) && isset($_GET['maxResults'])) {
  /*
   * Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
   * Google API Console <https://console.developers.google.com/>
   * Please ensure that you have enabled the YouTube Data API for your project.
   */
  //$DEVELOPER_KEY = 'REPLACE_ME';
  $DEVELOPER_KEY = getenv('API_KEY');//環境変数から取得
  $client = new Google_Client();//インスタンス化
  $client->setDeveloperKey($DEVELOPER_KEY); //APIKEYを入力して承認する

  // Define an object that will be used to make all API requests.
  $youtube = new Google_Service_YouTube($client);//YouTube Data APIは今後この変数を使用する

  $htmlBody = '';//HTMLに表示する中身を初期化
  try {

    // Call the search.list method to retrieve results matching the specified
    // query term.
    $searchResponse = $youtube->search->listSearch('id,snippet', array(
      'q' => $_GET['q'], //検索するキーワードを取得
      'maxResults' => $_GET['maxResults'], //取得する数の制限
    ));

    $videos = '';
    $channels = '';
    //$playlists = '';

    // Add each result to the appropriate list, and then display the lists of
    // matching videos, channels, and playlists.



    $video_number = 1; //動画のカウント
    $channel_number = 1; //チャンネルのカウント
    foreach ($searchResponse['items'] as $searchResult) {//検索にヒットした結果分処理を繰り返します。
      switch ($searchResult['id']['kind']) {
        case 'youtube#video':
          $videos .= sprintf('<div id="contents"><p>検索結果: %d<br>%s</p><p><a href="https://www.youtube.com/watch?v=%s" target="_blank"><img src ="%s"></a> <br>チャンネル名: %s <a href="https://www.youtube.com/channel/%s" target="_blank">投稿者のページへ</a></p></div>',
              $video_number, $searchResult['snippet']['title'], $searchResult['id']['videoId'], $searchResult['snippet']['thumbnails']['high']['url'], $searchResult['snippet']['channelTitle'],$searchResult['snippet']['channelId']);
              $video_number++;
          break;
        case 'youtube#channel':
          $channels .= sprintf('<div id="contents"><p>検索結果: %d</p><img src="%s"> <p>%s <a href="https://www.youtube.com/channel/%s" target="_blank">チャンネルページへ</a></p></div>',
              $channel_number, $searchResult['snippet']['thumbnails']['medium']['url'],$searchResult['snippet']['title'], $searchResult['id']['channelId']);
              $channel_number++;
          break;
        /*
        case 'youtube#playlist':
          $playlists .= sprintf('<li>%s (%s)</li>',
              $searchResult['snippet']['title'], $searchResult['id']['playlistId']);
          break;
          */
      }
    }

    $htmlBody .= <<<END
    <div id="title">
    <h2>検索結果はコチラです</h2>
    *動画をクリックすると動画のページへ移動します*
    </div>
    <h3>動画一覧</h3>
    <ul>$videos</ul>
    <h3>チャンネル一覧</h3>
    <ul>$channels</ul>

END;
  } catch (Google_Service_Exception $e) {
    $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
      htmlspecialchars($e->getMessage()));
  } catch (Google_Exception $e) {
    $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
      htmlspecialchars($e->getMessage()));
  }
}
?>

<!doctype html>
<html>
  <head>
    <title>YouTube Search</title>
    <!--CSSを直接埋め込んでいく-->
    <style>
      #title{
        text-align: center;
      }
      h3{
        text-align: center;
      }
      #contents{
        position: relative;
        left: 19%;
        text-align: center;
        width: 750px; 
        height: 500px;
        border-style: solid;
        border-color: lightblue;
      }
    </style>
  </head>
  <body>
    <?=$htmlBody?>
  </body>
</html>

実際に実行してみます。実行方法は先ほどと同様です。

検索キーワード: ポケモン
取得動画数: 10

実行結果1
youtubeDataAPI(改造結果1).PNG
実行結果2
youtubeDataAPI(改造結果2).PNG

しっかり動画とチャンネルが表示されていることが確認できます。また、リンクの接続も確認したところ上手くいきました。
APIから情報を取得し、表示することに成功しました。

最後に

今記事ではPHP初心者の私がAPIを使って簡単なプログラムを作成する過程を記事にさせていただきました。YouTube Data APIはまだまだたくさんの機能があるので是非自分で使っていただきたいです。

記事執筆を通じて「APIの使い勝手の良さ」、「公式ドキュメントの重要さ」を今一度確認することができました。
今後はAPIから取得したデータを収集、加工することでデータの活用を意識した開発を目指していたいです。
文章が拙い部分、厳密ではない部分があったと思いますが、読んでいただきありがとうございました。

ソースコードはGitHubアカウントにて公開しています。お時間がある方は覗いてみてください
最後に作成したコード(GitHub)

You-saku
独学だけでプログラミングを習得しようとしている者です。 独学なので自分のアウトプット頻度を上げるため、理解度チェックのために投稿させていただきます。記事への質問もお待ちしております。 記事の質が低いことが多々あります。申し訳ありません。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away