PHPの面白い小技です。
業務で使ったので公開します。
PHPのIteratorを実装して、
処理を簡潔に記述する方法。
※例外やSRPなどのクラス設計は無視。
Iteratorのサンプルとして提供します。
TwitterAPIのOAuthのサンプルにもなるかもです。
■処理概要
Twitterで
指定ユーザの全リストの全ユーザ情報(今回はスクリーン名のみ)を取得する処理。
■詳細
TwitterでOAuth認証した後に、
APIのList/Menberにアクセスしてユーザ情報を取得する。
■コード
(Iterator実装前)
// Listに含まれるユーザ情報を取得
function getMemberFromList( $lid ) {
$connect;
$next_cur = '-1';
$results = array();
do {
$req = false;
$api_url = "https://api.twitter.com/1/lists/members.xml?list_id={$lid}&cursor={$next_cur}";
$method = "GET";
$req = $connect->OAuthRequest( $api_url, $method );
if ( empty($req) ) return false;
$objXml = simplexml_load_string($req);
// 次ページ番号
$next_cur = (string)$objXml->next_cursor;
foreach($objXml->users->user as $user) {
$results[] = (string)$user->screen_name;
}
} while( $next_cur > 0 );
return ( !empty($results) )? $results: false;
}
(Iterator実装後)
リクエスト処理とページング処理を隠蔽。
う~ん、実にシンプル。二重ループは大目にみて(@@
// Listに含まれるユーザ情報を取得
function getMemberFromList( $lid ) {
$results = array();
$clsLM = new TListMember($lid);
// 一つの繰り返しが、1リクエスト取得分となる
// 対象が2ページあれば2回、1ページであれば1回まわる。
foreach( $clsLM as $lm ) {
foreach($lm->users->user as $user) {
$results[] = (string)$user->screen_name;
}
}
return ( !empty($results) )? $results: false;
}
■コード詳細
(Iteratorを実装した「TListMemberクラス」)
/**
* TwitterAPI list/memberクラス
*/
class TListMember implements Iterator {
private $index = 0; //現在位置
private $objXml;
private $connect;
private $lid;
public function __construct( $lid )
{
$this->lid = $lid;
// twitteroauthを利用
require_once('twitteroauth/twitteroauth.php');
$consumer_key = "■■■■";
$consumer_secret = "■■■■";
$access_token = "■■■■";
$access_token_secret = "■■■■";
// OAuthオブジェクトの生成
$this->connect = new TwitterOAuth($consumer_key, $consumer_secret, $access_token, $access_token_secret);
$this->connect->format = "xml";
$this->objXml = $this->getMemberList();
}
/**
* 現在の要素を返す
*/
public function current() {
return $this->objXml;
}
/**
* 現在の要素のキーを返す
*/
public function key() {
return $this->index;
}
/**
* 次の要素に進む
*/
public function next() {
$this->index++;
$this->objXml = $this->getMemberList((string)$this->objXml->next_cursor);
}
/**
* イテレータの最初の要素に巻き戻す
*/
public function rewind() {
$this->index = 0;
$this->objXml = $this->getMemberList();
}
/**
* 現在位置が有効かどうかを調べる
* @return 成功した場合に TRUE を、失敗した場合に FALSE を返します。
*/
public function valid() {
return !is_null($this->objXml);
}
// メンバー情報取得
private function getMemberList( $next_cur = -1 ){
if ($next_cur == 0) return null;
$req = false;
$api_url = "https://api.twitter.com/1/lists/members.xml?list_id={$this->lid}&cursor={$next_cur}";
$method = "GET";
$req = $this->connect->OAuthRequest( $api_url, $method );
if ( empty($req) ) return null;
return simplexml_load_string($req);
}
}