實作「YouTube API」套件在 Laravel 專案中使用(一)

前言

本文實作一個可以讀取 YouTube API 的套件。

專案目錄

專案目錄如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|- youtube-api/
|- component/
|- example/
|- index.php
|- src/
|- config/
|- youtube.php
|- Facades/
|- Youtube.php
|- Youtube.php
|- YoutubeServiceProvider.php
|- tests/
|- YoutubeTest.php
|- vendor/
|- .gitignore
|- composer.json
|- composer.lock
|- phpunit.xml
|- README.md

使用 YouTube API

YouTube API 提供詳細的文件供開發者使用。

申請 API Key

首先到 Google 開發者平台建立專案,並且取得 API Key。

安裝相依套件

建立 composer.json 檔。

1
2
3
4
5
6
7
8
{
"require": {
"guzzlehttp/guzzle": "^6.1"
},
"require-dev": {
"phpunit/phpunit": "^6.1"
},
}

安裝 GuzzlePHPUnit 相依套件。

1
composer install

實作

src 資料夾中新增一個 Youtube.php 檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
namespace Memo\Youtube;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

class Youtube
{
protected $client;
protected $url;
protected $key;
protected $params;

public function __construct($key)
{
$this->client = new Client();
$this->url = 'https://www.googleapis.com/youtube/v3';
$this->key = $key;
$this->params = [];
}

protected function setResource($type)
{
$this->url .= '/' . $type;
}

protected function setParams()
{
if (func_num_args() === 1) {
foreach (func_get_arg(0) as $key => $value) {
$this->params[$key] = $value;
}
}

if (func_num_args() === 2) {
$this->params[func_get_arg(0)] = func_get_arg(1);
}
}

protected function request()
{
$this->setParams('key', $this->key);

$url = $this->url . '?' . http_build_query($this->params);

try {
$response = $this->client->get($url)->getBody();
} catch (ClientException $e) {
$response = $e->getResponse()->getBody()->getContents();
}

return json_decode($response);
}

public function getChannelByName($username, array $part = ['id', 'snippet', 'contentDetails', 'statistics', 'brandingSettings'])
{
$this->setResource('channels');

$this->setParams([
'part' => implode(', ', $part),
'forUsername' => $username,
]);

return $this->request();
}
}

測試

新增一個 phpunit.xml 檔,並將 API Key 設為環境變數。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix="Test.php">./tests/</directory>
</testsuite>
</testsuites>
<php>
<env name="YOUTUBE_API_KEY" value="YOUTUBE_API_KEY"/>
</php>
</phpunit>

tests 資料夾新增一個 YoutubeTest.php 檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
namespace Memo\Youtube\Tests;

use Memo\Youtube\Youtube;
use PHPUnit\Framework\TestCase;

class YoutubeTest extends TestCase
{
public $youtube;

public function setUp()
{
$this->youtube = new Youtube(getenv("YOUTUBE_API_KEY"));
}

public function testGetChannel()
{
$response = $this->youtube->getChannel('Google');

$this->assertEquals('youtube#channel', $response->items[0]->kind);
$this->assertEquals('Google', $response->items[0]->snippet->title);

$this->assertObjectHasAttribute('id', $response->items[0]);
$this->assertObjectHasAttribute('snippet', $response->items[0]);
$this->assertObjectHasAttribute('contentDetails', $response->items[0]);
$this->assertObjectHasAttribute('statistics', $response->items[0]);
$this->assertObjectHasAttribute('brandingSettings', $response->items[0]);
}

public function tearDown()
{
$this->youtube = null;
}
}

執行測試。

1
vendor/bin/phpunit

使用

example 資料夾新增一個 index.php 檔。

1
2
3
4
5
6
7
8
require '../vendor/autoload.php';
require '../src/Youtube.php';

use Memo\Youtube\Youtube;

$youtube = new Youtube('API Key');

var_dump($youtube->getChannelByName('Google'));

程式碼