PHPで放映中のアニメ一覧を表示

(1/1)
今回は、PHPで「ShangriLa Anime API」を利用し、指定した西暦年、クールで放映されているアニメ一覧を表示するプログラムをつくる。また、「PHPでTwitterに投稿(ツイート)する」で作った Twitter APIをクラウド連携し、そのアニメのTwitterバナー画像を表示できるようにする。

目次

サンプル・プログラム:実行例(バナー画像あり)

PHPで放映中のアニメ一覧を表示

サンプル・プログラム

圧縮ファイルの内容
onairAnime.phpサンプル・プログラム本体。
pahooTwitterAPI.phpTwitter APIを利用するクラス pahooTwitterAPI。
使い方は「PHPでTwitterに投稿(ツイート)する」などを参照。include_path が通ったディレクトリに配置すること。

解説:初期値

0021: //プログラム・タイトル
0022: define('TITLE', '放映中のアニメ一覧');
0023: 
0024: //表示幅(ピクセル)
0025: define('WIDTH', 600);
0026: 
0027: //バナー画像を表示するかどうか(TRUE:表示する)
0028: define('BANNER', FALSE);
0029: 
0030: //Spinner - jQuery UIを使用するかどうか(TRUE:使用する)
0031: define('USESPINNER', TRUE);
0032: 
0033: //Twitter APIクラス:include_pathが通ったディレクトリに配置
0034: if (BANNER) {
0035:     require_once('pahooTwitterAPI.php');
0036: }

変更不可の記載がない定数については自由に変更できる。

定数 BANNERTRUE にすることで、そのアニメのTwitterバナー画像を表示できるようにする。TRUE にすることで、Twitter APIを利用するクラス pahooTwitterAPI を利用するようになるので、後述する Twitter API クラス を参照のこと。
定数 USESPINNERTRUE にすることで、数値選択のための Spinner - jQuery UI が利用できるようになる。

ShangriLa Anime API

ShangriLa Anime API は、Apache 2.0 Licenseのもとアニメ作品の基本情報をREST API形式で返すAPIサーバーである。APIパスに、検索対象となる西暦年、クールを指定する。
ShangriLa Anime API
URL
https://api.moemoe.tokyo/anime/v1/master/:year/:cours

入力パラメータ
フィールド名 要否 内  容
year 必須 西暦年
cours 必須 クール(1~4)
応答データ(json) id ユニークID title 作品名 title_short1 略称1 title_short2 略称2 title_short3 略称3 public_url 公式URL twitter_account Twitterアカウント twitter_hash_tag Twitterハッシュタグ cours_id coursマスターID sex 男性向け=0, 女性向け=1 sequel 続編カウンタ created_at データ作成日時 updated_at データ更新日時

0224: /**
0225:  * アニメ一覧取得
0226:  * @param   int    $year   西暦年
0227:  * @param   int    $cours  クール(1~4)
0228:  * @param   string $webapi APIコールURLを格納
0229:  * @param   array  $items  応答情報を格納
0230:  * @param   string $errmsgエラーメッセージを格納
0231:  * @return  bool TRUE:正常応答/FALSE:異常応答
0232: */
0233: function searchAnime($year$cours, &$url, &$items, &$errmsg) {
0234:     //引数エラーチェック
0235:     if (($cours < 1) || ($cours > 4)) {
0236:         $errmsg = 'クールが1未満,または4を超える値です';
0237:         return FALSE;
0238:     }
0239: 
0240:     //APIコール
0241:     $url = sprintf('https://api.moemoe.tokyo/anime/v1/master/%d/%d', $year$cours);
0242:     $infp = @fopen($url, 'r');
0243:     if ($infp == FALSE) {
0244:         $errmsg = 'WebAPIが停止しています';
0245:         return FALSE;
0246:     }
0247: 
0248:     //応答情報取得
0249:     $items = json_decode(file_get_contents($url));
0250: 
0251:     fclose($infp);
0252: 
0253:     //応答件数チェック
0254:     if (count($items) < 1) {
0255:         $errmsg = '放映情報がありません';
0256:         return FALSE;
0257:     }
0258: 
0259:     return TRUE;
0260: }

PHPプログラムでは、APIを呼び出す手続きをクラス pahooShangriLaAnimeAPI のメソッド searchAnime として実装した。

Twitter API:GET users/profile_banner

対象ユーザーのバナー画像のURLを取得するためのTwitter APIである。
15分間に180回という呼び出し制限があるが、今回のプログラムでは、この制約の影響を受けることはないだろう。
Twitter API (GET)
URL
https://api.twitter.com/1.1/users/profile_banner.json

入力パラメータ
フィールド名 要否 内  容
user_id user_id または screen_name のどちらか必須 ユーザーID
screen_name スクリーンネーム
応答データ(json) sizes ipad h 高さ(ピクセル):313 w 幅(ピクセル):626 url 画像URL ipad_retina h 高さ(ピクセル):626 w 幅(ピクセル):1252 url 画像URL web h 高さ(ピクセル):260 w 幅(ピクセル):520 url 画像URL web_retina h 高さ(ピクセル):520 w 幅(ピクセル):1040 url 画像URL mobile h 高さ(ピクセル):160 w 幅(ピクセル):320 url 画像URL mobile_retina h 高さ(ピクセル):320 w 幅(ピクセル):640 url 画像URL 300x100 h 高さ(ピクセル):100 w 幅(ピクセル):300 url 画像URL 600x200 h 高さ(ピクセル):200 w 幅(ピクセル):600 url 画像URL 1500x500 h 高さ(ピクセル):500 w 幅(ピクセル):1500 url 画像URL

0622: /**
0623:  * バナー画像を取得する
0624:  * @param   string $screen_nameスクリーンネーム
0625:  * @return  stringバナー画像(1500×500)のURL
0626: */
0627: function profile_banner($screen_name) {
0628:     static $url    = 'https://api.twitter.com/1.1/users/profile_banner.json';
0629:     static $method = 'GET';
0630:     $option['screen_name'] = $screen_name;
0631: 
0632:     $results = array();
0633:     $res = $this->request_user($url$method$option);
0634:     if ($res == FALSE)  return FALSE;
0635: 
0636:     return (isset($this->responses->sizes->{'1500x500'}->url)) ? $this->responses->sizes->{'1500x500'}->url : FALSE;
0637: }

PHPプログラムでは、pahooTwitterAPI クラスのメソッド profile_banner として実装し、1500×500ドットの画像URLを取得できるようにした。

放映中のアニメ一覧

0265: /**
0266:  * HTML BODYを作成する
0267:  * @param   int    $year   西暦年
0268:  * @param   int    $cours  クール(1~4)
0269:  * @param   array  $items  応答情報
0270:  * @param   string $webapi WebAPIのURL
0271:  * @param   string $errmsgエラーメッセージ
0272:  * @return  string HTML
0273: */
0274: function makeCommonBody($year$cours$items$webapi$errmsg) {
0275:     if (BANNER) {
0276:         //オブジェクト生成
0277:         $ptw = new pahooTwitterAPI();
0278:     }
0279: 
0280:     $myself = MYSELF;
0281:     $refere = REFERENCE;
0282:     $width  = WIDTH;
0283:     $title  = TITLE;
0284:     $version = '<span style="font-size:small;">' . date('Y/m/d版', filemtime(__FILE__)) . '</span>';
0285:     $width_image = (int)WIDTH / 3;
0286:     $table = '';
0287: 
0288:     //デバッグ情報
0289:     if (! FLAG_RELEASE) {
0290:         $phpver = phpversion();
0291: $debug =<<< EOT
0292: <p>
0293: <span style="font-weight:bold;">★デバックモードで動作中...</span><br />
0294: PHPver : {$phpver}<br />
0295: WebAPI : <a href="{$webapi}">{$webapi}</a>
0296: 
0297: EOT;
0298:     }
0299: 
0300:     //エラーメッセージ
0301:     if ($errmsg != '') {
0302: $errmsg =<<< EOT
0303: <p style="color:red">
0304: エラー:{$errmsg}.
0305: </p>
0306: 
0307: EOT;
0308:     } else if (count($items) > 0){
0309:         if (BANNER) {
0310:             $label = "<th>バナー画像</th>\n";
0311:         } else {
0312:             $label = '';
0313:         }
0314: $table =<<< EOT
0315: <table class="plists">
0316: <tr>
0317: <th>作品名</th>
0318: <th>Twitterアカウント<br />ハッシュタグ</th>
0319: {$label}
0320: </tr>
0321: 
0322: EOT;
0323:         $cnt = -1;
0324:         foreach ($items as $key=>$val) {
0325:             //タイトル+公式サイト
0326:             if (isset($val->public_url) && ($val->public_url != '')) {
0327:                 $anime = "<a href=\"{$val->public_url}\">{$val->title}</a>";
0328:             } else {
0329:                 $anime = $val->title;
0330:             }
0331:             //Twitterアカウント+バナー画像
0332:             if (isset($val->twitter_account) && ($val->twitter_account != '')) {
0333:                 $twitter = "<a href=\"https://www.twitter.com/{$val->twitter_account}/\">@{$val->twitter_account}</a>";
0334:                 if (BANNER) {
0335:                     $image = $ptw->profile_banner($val->twitter_account);
0336:                     if ($image != FALSE) {
0337:                         $image = "<td><img style=\"width:{$width_image}px;\" src=\"{$image}\" /></td>";
0338:                     } else {
0339:                         $image  = '<td>&nbsp;</td>';
0340:                         //エラー・リセット
0341:                         $ptw->error = FALSE;
0342:                         $ptw->errmsg = '';
0343:                         $ptw->errcode = 0;
0344:                     }
0345:                 } else {
0346:                     $image  = '';
0347:                 }
0348:             } else {
0349:                 $twitter = '';
0350:                 if (BANNER) {
0351:                     $image  = '<td>&nbsp;</td>';
0352:                 } else {
0353:                     $image  = '';
0354:                 }
0355:             }
0356:             //Twitterハッシュタグ
0357:             if (isset($val->twitter_hash_tag) && ($val->twitter_hash_tag != '')) {
0358:                 $hashtag = "<br /><a href=\"https://twitter.com/search?q=%23{$val->twitter_hash_tag}\">#{$val->twitter_hash_tag}</a>";
0359:             } else {
0360:                 $hashtag = '';
0361:             }
0362: 
0363: $table .=<<< EOT
0364: <tr>
0365: <td>{$anime}</td>
0366: <td>{$twitter}{$hashtag}</td>
0367: {$image}
0368: </tr>
0369: 
0370: EOT;
0371:         }
0372:         $table .= "</table>\n";
0373:     } else {
0374:         $table = '';
0375:     }
0376: 
0377: $html =<<< EOT
0378: <body>
0379: <h2>{$title} {$version}</h2>
0380: <form name="myform" method="get" action="{$myself}">
0381: 西暦年 <input name="year" id="year" type="text" size="3" value="{$year}" /> 
0382: クール <input name="cours" id="cours" type="text" size="2" value="{$cours}" /> 
0383: <input name="exec" id="exec" type="submit" value="検索" />
0384: <input name="reset" id="reset" type="submit" value="リセット" />
0385: </form>
0386: {$errmsg}
0387: {$table}
0388: 
0389: <div style="border-style:solid; border-width:1px; margin:20px 0px 0px 0px; padding:5px; width:{$width}px; font-size:small; overflow-wrap:break-word; word-break:break-all;">
0390: <h3>使い方</h3>
0391: <ol>
0392: <li>[<span style="font-weight:bold;">西暦年</span>]を選択してください.</li>
0393: <li>[<span style="font-weight:bold;">クール</span>](1~4)を選択してください.</li>
0394: <li>[<span style="font-weight:bold;">検索</span>]ボタンを押してください.</li>
0395: <li>[<span style="font-weight:bold;">リセット</span>]ボタンを押すと,初期化します.</li>
0396: </ol>
0397: ※参考サイト:<a href="{$refere}">{$refere}</a>
0398: {$debug}
0399: </div>
0400: </body>
0401: 
0402: EOT;
0403:     if (BANNER) {
0404:         //オブジェクト解放
0405:         $ptw = NULL;
0406:     }
0407: 
0408:     return $html;
0409: }

ShangriLa Anime API の応答結果を一覧表示するユーザー関数が makeCommonBody である。

応答結果をHTMLのTABLEタグに変換する。
応答結果のTwitterアカウントが消滅している場合もあるので、このときはエラー・リセットのために pahooTwitterAPI クラスを再オブジェクト化している。

参考サイト

(この項おわり)
header