PHPでTwitter相互フォローを表示

(1/1)
今回は、PHP で「Twitter API」を利用し、複数ユーザーの間のフォロー関係がどうなっているかを調べるプログラムをつくってみることにする。
Twitter API の制約で、フォローしているユーザーが極端に多いと調査しきれないが、個人用との範囲なら、それほど問題にはならないだろう。

サンプル・プログラム:実行例

PHPでTwitter相互フォローを表示
「ユーザーリスト」に調べたいユーザー(スクリーンネーム)を改行区切りで記入し、「調査」ボタンを押下すると、ユーザー間のフォロー関係を一覧表示する。

サンプル・プログラム

Twitter API クラス

Twitter API を利用する関数群はクラス pahooTwitterAPI として別ファイル "pahooTwitterAPI.php" に定義してある。このファイルを  require_once  できるパスに配置すること。

OAuth認証を利用するため、プログラムを Twitter に登録する必要がある。その手順については「PHP で Twitter に投稿(ツイート)する」を参照のこと。取得したパラメータは、クラス pahooTwitterAPI 冒頭にあるクラス定数に記載すること。

https通信を使うため、PHP から OpenSSL を利用できるようにしておく必要がある。その手順は「PHP の https 対応」を参照のこと。
プログラムがうまく動かなかったら、「Twitter への再登録が必要な場合も」を参照のこと。

Twitter API:GET users/show

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

入力パラメータ
項目名 フィールド名 内  容
ユーザーID user_id string user_id または screen_name の【どちらか必須】
スクリーンネーム screen_name string user_id または screen_name の【どちらか必須】
フレームの最大横幅 include_entities string ツイートオブジェクト内のentitiesプロパティを含めるか否かをTRUEまたはFALSEで指定する。【デフォルト:TRUE】
応答データ(json) id ユーザーID id_str ユーザーID(文字列) name ユーザー名 screen_name スクリーンネーム location 場所 description プロフィール created_at アカウント作成日時 profile_image_url プロフィール画像URL

Twitter API:GET friends/ids

フォローしているユーザーを ID の一覧で取得するための Twitter API である。
15 分間に 15 回という呼び出し制限がある。一度に取得できるフォロー数は 5,000 件であるため、一度に 75,000 件が最大となる。5 つのユーザーを調べるとすると、1 ユーザーあたり 75,000÷5=平均 12,500 件のフォロー数が限界となる。プログラム中で API エラーをキャッチアップしている。
Twitter API (GET)
URL
https://api.twitter.com/1.1/friends/ids.json

入力パラメータ
項目名 フィールド名 内  容
ユーザーID user_id string user_id または screen_name の【どちらか必須】
スクリーンネーム screen_name string user_id または screen_name の【どちらか必須】
ページング開始位置 cursor string ページングをする際の取得開始位置を示すカーソルを指定する。カーソルは、リクエストした際のprevious_cursor(前ページ)、またはnext_cursor(次ページ)に含まれる。
IDを文字列型に stringify_ids string 通常は数値型のユーザーIDを、文字列型にして取得するか否か。TRUEなら文字列、FALSEなら数値で取得する。Twitterの各種IDは桁数が多く、サーバーによっては末尾の数値が丸められてしまうため、文字列として扱うことを推奨している。【デフォルト:TRUE】
取得数 count integer 結果の数。1〜5,000の間で指定できる。
応答データ(json) ids フォローID(配列) next_cursor 次のカーソル next_cursor_str 次のカーソル(文字列) previous_cursor 前のカーソル previous_cursor_str 前のカーソル(文字列)

解説:ユーザーを取得する

0457: /**
0458:  * ユーザーを取得する
0459:  * @param string $screen_name スクリーンネームまたはユーザーID
0460:  * @return array ユーザー情報
0461: */
0462: function users($screen_name) {
0463:     static $url_users = 'https://api.twitter.com/1.1/users/show.json';
0464:     static $method    = 'GET';
0465:     $option  = array();
0466:     $results = array();
0467: 
0468:     //スクリーンネームとユーザーIDの判別
0469:     if (preg_match('/^[0-9]+$/i', $screen_name) == 0) {
0470:         $option['screen_name'] = $screen_name;
0471:     } else {
0472:         $option['user_id'] = $screen_name;
0473:     }
0474: 
0475:     $res = $this->request_user($url_users$method$option);
0476: 
0477:     if ($res == FALSE)  return FALSE;
0478: 
0479:     $results['id'] = $this->responses->id_str;
0480:     $results['name'] = $this->responses->name;
0481:     $results['screen_name'] = $this->responses->screen_name;
0482:     $results['description'] = $this->responses->description;
0483:     $results['created_at'] = $this->responses->created_at;
0484:     $results['profile_image_url'] = $this->responses->profile_image_url;
0485: 
0486:     return $results;
0487: }

基本的には、「PHP で Twitter に投稿(ツイート)する」とで解説したリクエスト関数 request_user と同じである。

0191:     $this->responses = json_decode($jsonFALSE, 512, JSON_BIGINT_AS_STRING);

ユーザー ID は数字だけで構成されている。
PHP 処理系で長大な整数と誤認識されるのを避けるため、メソッド request_user を少し改め、組み込み関数  json_decode  で長大な整数を文字列とみなすよう JSON_BIGINT_AS_STRING を指定するようにした。

解説:フォローしているユーザーをID一覧で取得する

0489: /**
0490:  * フォローしているユーザーをID一覧で取得する
0491:  * @param string $screen_name スクリーンネーム
0492:  * @return array ID一覧
0493: */
0494: function friends($screen_name) {
0495:     static $url_friends = 'https://api.twitter.com/1.1/friends/ids.json';
0496:     static $method         = 'GET';
0497:     $option['screen_name'] = $screen_name;
0498:     $option['count']       = 5000;
0499: 
0500:     $results = array();
0501:     $cnt = 1;
0502:     //5000件ずつ取得
0503:     do {
0504:         $res = $this->request_user($url_friends$method$option);
0505:         if ($res == FALSE)  return FALSE;
0506:         foreach ($this->responses->ids as $key=>$id) {
0507:             $str = (string)$id;
0508:             $results[$cnt] = (string)$id;
0509:             $cnt++;
0510:         }
0511:     } while ($this->responses->next_cursor != 0);
0512: 
0513:     return $results;
0514: }

こちらも users とほぼ同じだが、取得件数が最大 5,000 件であるため、それを超えるフォローをしている場合は、繰り返し呼び出しで 5,000 件を超えるようにしている。

解説:相互フォロー表を作成

0161: /**
0162:  * 相互フォロー表を作成
0163:  * @param string $userlist ユーザーリスト
0164:  * @param array  $items    調査結果を格納する配列
0165:  * @param array  $names    ユーザー名一覧を格納する配列
0166:  * @return string エラーメッセージ/''
0167: */
0168: function getTwitterFolower($userlist, &$items, &$names) {
0169:     $ptw = new pahooTwitterAPI();    //TwitterAPIクラス
0170: 
0171:     $users = array();
0172:     $follows = array();
0173: 
0174:     if ($userlist == '')   return 'ユーザー情報がありません';
0175: 
0176:     //ユーザー情報取得
0177:     $arr = preg_split("/\n/ui", $userlist);
0178:     $cnt = 0;
0179:     foreach ($arr as $val) {
0180:         $user = trim($val);
0181:         if ($user != '') {
0182:             $results = $ptw->users($user);
0183:             if ($results == FALSE) {
0184:                 return $user . ' のユーザー情報が取得できません';
0185:             } else {
0186:                 $users[$cnt]['screen_name'] = $user;
0187:                 $users[$cnt]['id']   = $results['id'];
0188:                 $names[$user] = $results['name'];
0189:                 $cnt++;
0190:             }
0191:         }
0192:     }
0193:     //フォロー情報取得
0194:     for ($i = 0; $i < $cnt$i++) {
0195:         $sour = $users[$i]['screen_name'];
0196:         $results = $ptw->friends($sour);
0197:         if ($results == FALSE) {
0198:             return $sour . ' のフォロー情報が取得できません';
0199:         } else {
0200:             for ($j = 0; $j < $cnt$j++) {
0201:                 $dest = $users[$j]['screen_name'];
0202:                 $res = array_search($users[$j]['id'], $results);
0203:                 $follows[$sour][$dest] = $res;
0204:             }
0205:         }
0206:     }
0207:     //相互フォロー表作成
0208:     for ($i = 0; $i < $cnt$i++) {
0209:         $sour = $users[$i]['screen_name'];
0210:         for ($j = $i$j < $cnt$j++) {
0211:             $dest = $users[$j]['screen_name'];
0212:             if ($follows[$sour][$dest] != FALSE) {
0213:                 $items[$sour][$dest] = FOLLOW1;
0214:                 if ($follows[$dest][$sour] != FALSE) {
0215:                     $items[$sour][$dest] = FOLLOW3;
0216:                 }
0217:             }
0218:         }
0219:     }
0220:     return '';
0221: }

まず、ユーザーリストを分解し、配列 $users に入れていく。
このとき、前述の pahooTwitterAPI::users を呼び出し、ユーザー ID とユーザー名を取得する。ユーザー名は別の配列 $names に格納する。

続いて、配列 $users の要素ひとつずつ、前述の pahooTwitterAPI::friends を呼び出し、配列 $users に合致するユーザーをフォローしていれば、その結果を配列 $follows に入れていく。

最後に、配列 $follows を総なめして、結果を配列 $items に代入すると同時に、相互フォローの場合とそうでない場合とで異なる記号を代入していく。

参考サイト

(この項おわり)
header