6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PHPのIteratorを実装してみた

Last updated at Posted at 2013-02-28

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);
  }
}
6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?