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

(1/1)
今回は、PHP で「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/friendships/show.json

入力パラメータ
項目名 フィールド名 内  容
元となるユーザーID source_id string source_id または source_screen_name の【どちらか必須】
元となるスクリーンネーム source_screen_name string source_id または source_screen_name の【どちらか必須】
相手のユーザーID target_id string target_id または target_screen_name の【どちらか必須】
相手のスクリーンネーム target_screen_name string target_id または target_screen_name の【どちらか必須】
応答データ(json) relationship source id ユーザーID id_str ユーザーID(文字列) screen_name スクリーンネーム following TRUE/FALSE following_by TRUE/FALSE blocking TRUE/FALSE blocking_by TRUE/FALSE target id ユーザーID id_str ユーザーID(文字列) screen_name スクリーンネーム following TRUE/FALSE following_by TRUE/FALSE

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

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 を指定するようにした。

解説:指定のユーザ同士のフォロー関係を取得する

0516: /**
0517:  * 指定のユーザ同士のフォロー関係を取得する
0518:  * @param string $source スクリーンネーム
0519:  * @param string $target スクリーンネーム
0520:  * @return int 0:関係なし, 1:source→target, 2:source←target,
0521:  *              3:source⇔target(双方向), FALSE:取得失敗
0522: */
0523: function friendships($source$target) {
0524:     static $url    = 'https://api.twitter.com/1.1/friendships/show.json';
0525:     static $method = 'GET';
0526:     $option['source_screen_name'] = $source;
0527:     $option['target_screen_name'] = $target;
0528: 
0529:     $results = array();
0530:     $res = $this->request_user($url$method$option);
0531:     if ($res == FALSE)  return FALSE;
0532: 
0533:     $res = 0x00;
0534:     if (isset($this->responses->relationship->source->following)
0535:         && (bool)$this->responses->relationship->source->following) {
0536:             $res |= 0x01;
0537:     }
0538:     if (isset($this->responses->relationship->target->following)
0539:         && (bool)$this->responses->relationship->target->following) {
0540:             $res |= 0x02;
0541:     }
0542: 
0543:     return $res;
0544: }

こちらも users とほぼ同じだが、指定のユーザーの関係性を数値として返すようにしてある。

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

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

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

続いて、配列 $users の要素ひとつずつ、前述の pahooTwitterAPI::friendships を呼び出し、フォロー関係を配列 $items に入れていく。
フォロー関係は双方向チェックしているので、配列 [$users] の半分だけ調べてやれば網羅性があることに留意。

参考サイト

(この項おわり)
header