2022/03/15 (火)

PHPで何か作るよ(1) - ニコ動マイリスト取得

●「PHPで何か作るよ」コーナー始めました

  • JavaScriptに続き、PHPでも何か作ります。
  • まずは先日の「nnplay」用の動画データ作成ツールから。
  • できました→ nnlist(正式名:NicoNicoLister)

  • nnlistは2つの部分から構成されます。
    nnlist.html — HTMLとJavaScriptで書かれたフロントエンド。
    nnlist.php — ニコニコ動画のマイリストを取得する実働班。
  • 今回の記事ではPHP部分のnnlist.phpをとりあげます。

●nnlist.phpの呼び出し方

  • nnlist.phpは、URLに「?id=マイリスト番号」を付けて呼び出します。たとえば次のような感じです。
    https://and.crap.jp/desga/nanika/nnlist.php?id=65848924
  • ちなみにこれは、そば処五三郎さんの「架空ゲームシリーズ」のマイリストを取得しています。
  • 実行すると次の結果が得られます。
    <!– mylist/65848924 「架空ゲームシリーズ」 by そば処五三郎 –>
    <option value=”sm7038338”>チートクエスト</option>
    <option value=”sm7357746”>破格の錬金術師</option>
    <option value=”sm7542750”>魔法が使えるゲーム</option>
    <option value=”sm7966523”>親切設計のゲーム</option>
    <option value=”sm8175013”>イエスマン</option>
    <option value=”sm35443647”>設定を変えられるゲーム</option>
    <option value=”sm35538035”>設定を変えられる実況プレイ動画</option>
    <option value=”sm35628885”>属性の多い道具店</option>
  • これをそのままnnplayのHTMLに組み込んで利用するわけです。

●nnlist.phpのソースコード

  • ソースコードはこんな感じです。
  • どの行もPHPの基本処理で、特に説明とかいらない感じですが…。
  • いちおう備忘メモとして、いくつか能書きを並べてみます。

  • 5行目: URLに付けた引数「id=番号」は、$_GET[’id’]で取得できます。
  • もしid引数がない場合、$_GET[’id’]を取得すると警告がでますが、
  • null合体演算子「??」でチェックすると、その警告を回避できます。

  • 12~14行目: ニコ動のマイリストは次のようなURLで取得できます。
    例→ https://www.nicovideo.jp/mylist/65848924?rss=2.0
  • 外部のWebサイトからデータを取得するにはfile_get_contents()を使います。
  • このとき13行目のオプションをアクセス時に付けるとエラー中断を回避できます。

  • 17~20行目: 特殊配列 $http_response_header[] には、すべてのHTTPレスポンスヘッダが入ります。
  • $http_response_header[0] は「HTTP/1.1 200 OK」などのステータスです。
  • ステータスコードが200なら成功です。

  • 24行目: ニコニコ動画から得た結果をXMLとして解析します。
  • XMLの処理方法はいろいろですが、当ブログではSimpleXMLを利用します。

  • 29行目: SimpleXMLライブラリでは、XMLの要素の入れ子をアロー演算子でたどれます。
  • たとえば <rss>内の <channel>内の <title> という要素の入れ子は、
    「$rss->channel->title」と書けるわけです。

  • 31行目: ただしXMLの要素名が「PHPの変数名」として使えない文字を含む場合は、特別な処理が必要です。
  • たとえば <dc:creator> という要素は、名前にコロン「:」が入るため、「$rss->channel->dc:creator」などと書けません。
  • 今回のプログラムではxpath(”//dc:creator”)ですべての<dc:creator>を配列化し、その最初の1個を取り出しています。
  • ちょっと強引でした。もっと良いやり方があるかもしれません。

  • ★追記★
  • <dc:creator> を得る別解です。このほうが良いかも。
  • 「dc:」で始まる要素をchildren()で列挙した上でcreatorを得ます。
    $creator = $rss->channel->children(”dc”, true)->creator;