‘PHP’ カテゴリーのアーカイブ

PhalconのコマンドラインでError: This command should be invoked inside a Phalcon project directory

phalcon create-modelをしようとして、上記エラーが発生しました。

プロジェクトディレクトリで実行しろということなのですが、プロジェクトディレクトリには既にいるはず…

Error: This command should be invoked inside a Phalcon project directory – Discussion – Phalcon Framework

上記サイトでは.phalconファイルを作成すれば良いという話。が、正解は.phalconディレクトリを作る必要があります。

結局のところ、プロジェクトを自分で作った人ではなく、リポジトリからダウンロードしてきた場合に多く発生します。

というのも、自分のところはMercurialですが、中身が空のディレクトリがリポジトリに登録できないという仕様なので、.phalconディレクトリをリポジトリにコミットし損ねていたということですね。

$ mkdir ./.phalcon
$ touch ./.phalcon/empty

などとして、ファイルを追加してコミットしておけば解決です。


SensioBuzzBundleでname lookup timed outになる問題

やっとSymfony 2.3使い始めました。

コントローラーから、外部APIへのリクエストにSensioBuzzBundleを使っているのですが、cURLのDNS名前解決に時間がかかるようで、タイムアウトが頻発していました。

sensiolabs/SensioBuzzBundle

解決については設定を追加すれば良いようです。

app/config/config.ymlに

sensio_buzz:
    client_timeout: 100

などと追加するだけです。

ソースコードを見る限り、デフォルトは5秒のようです。

SensioBuzzBundle/DependencyInjection/Configuration.php at master · sensiolabs/SensioBuzzBundle


symfonyでlessを使えるようにするsfLESSPluginの使い方

Symfony 1.4で作ったWebサイトでbootstrapのカスタマイズをしたくなったのでlessのツールを探していたらsfLESSPluginという便利そうなものを見つけました。

Plugins | sfLESSPlugin | 1.1.0 | symfony | Web PHP Framework
https://github.com/everzet/sfLESSPlugin

lessファイルを置くだけでcssにコンパイルして表示できるプラグインです。

sfLessPhpPluginというものもあったようなのですが、sfLESSPluginになったようです。作者は同じです。

Plugins | sfLessPhpPlugin | 1.3.3 | symfony | Web PHP Framework

$ ./symfony plugin:install sfLESSPlugin

これでインストールはできるのですが、バージョン番号は同じもののgithubにあるファイルより古いので、githubから最新のファイルをインストールします。

ちなみに現時点で最新のコミットは以下ですが、PHP単体でlessをコンパイルできるlessphpが使えるようになっています。古いものはnode.jsが必要です。

https://github.com/everzet/sfLESSPlugin/commit/738e274ed131e9bdfad3bed7c2c4d031baf1511c

$ cd plugins/

$ git clone git://github.com/everzet/sfLESSPlugin.git
Cloning into sfLESSPlugin...
remote: Counting objects: 359, done.
remote: Compressing objects: 100% (176/176), done.
remote: Total 359 (delta 197), reused 317 (delta 161)
Receiving objects: 100% (359/359), 85.71 KiB | 131 KiB/s, done.
Resolving deltas: 100% (197/197), done.

$ cd ..

次にlessファイルを置くディレクトリを作ります。

$ mkdir web/less
$ cd web/less
$ wget https://github.com/twitter/bootstrap/zipball/v2.0.4 -O bootstrap.zip
$ unzip ./bootstrap.zip
$ mv ./twitter-bootstrap-41d3220/less/*.less ./
$ rm -R ./twitter-bootstrap-41d3220
$ rm ./bootstrap.zip
$ cd ../..

gitでダウンロードしたので、プラグインが自動的に有効になりません。

config/ProjectConfiguration.class.php

にenablePluginsを追加してプラグインを有効にします。

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->enablePlugins('sfLESSPlugin');
    $this->enablePlugins('sfDoctrinePlugin');
  }
}

publish-assetsを実行してwebにプラグインのリンクを作ります。

$ ./symfony plugin:publish-assets

app/frontend/templates/layout.phpを編集します。

<?php use_helper('LESS'); ?>

を先頭に、

<?php include_less_stylesheets() ?>

を<?php include_stylesheets() ?>の代わりに指定します。

app/fronend/config/view.ymlにbootstrapのlessファイルを指定します。

stylesheets:    [bootstrap.less]

ちなみに、既存のcssも混在できます。

stylesheets:    [bootstrap.less, main.css]

その場合、cssファイルは今までどおり/cssから読み込まれます。

sfLESSPluginはブラウザサイドでlessファイルをless.jsで読み込んで解釈する方法と、サーバサイドでCSSとしてコンパイルしておく方法が使えます。

まずはブラウザサイドの動作を確認します。

ここまでで一度ブラウザで表示してみると、

/sfLESSPlugin/js/less-1.1.3.min.jsが404エラーになります。

plugins/sfLESSPlugin/web/jsを見ると、less-1.0.30.min.jsしか入っていないのでバージョンが違っています。

なぜかこのファイルは

plugins/sfLESSPlugin/lib/config/LESSConfig.class.php

でハードコーディングされています。

sfLESSのコンストラクタに独自のLESSConfigオブジェクトを渡せば変更できるようなのですが、それもハードコーディングされていたので諦めてLESSConfig.class.phpを書き換えてしまいます。

先にless.jsをダウンロードしてきます。

LESS « The Dynamic Stylesheet language

現時点では1.3.0が最新でした。

$ cd ./plugins/sfLESSPlugin/web/js/
$ wget http://lesscss.googlecode.com/files/less-1.3.0.min.js
$ cd ../../../../

plugins/sfLESSPlugin/lib/config/LESSConfig.class.php

を書き換えます。

  public function getLessJsPath()
  {
    // return '/sfLESSPlugin/js/less-1.1.3.min.js';
    return '/sfLESSPlugin/js/less-1.3.0.min.js';
  }

これでブラウザサイドでbootstrapをコンパイルする準備ができました。

ブラウザで確認すると、正常にbootstrapのCSSが効いていることがわかると思います。

このままではlessファイルを大量にリクエストすることになるので、次はサーバサイドでコンパイルして使うようにします。

ドキュメントにはnode.jsを使う方法が書いてありますが、せっかく新しいバージョンでlessphpが使えるようになったので、lessphpを試してみます。

まず、lessphpをダウンロードします。

lessphp – LESS compiler in PHP

$ cd ./lib/vendor
$ wget http://leafo.net/lessphp/src/lessphp-0.3.5.tar.gz
$ tar xvzf ./lessphp-0.3.5.tar.gz
$ mv ./lessphp/lessc.inc.php ./
$ rm -R ./lessphp
$ rm ./lessphp-0.3.5.tar.gz
$ cd ../..

必要なのはlessc.inc.phpだけです。また、ファイルはlib/vendor/lessc.inc.phpに置くように決められています。

で、また設定が

plugins/sfLESSPlugin/lib/config/LESSConfig.class.php

にあります。

  // protected $useLessphp = false;
  protected $useLessphp = true;

config/app.ymlに設定を書きます。less.jsを使用せず、コンパイルを有効にします。

  sf_less_plugin:
    compile:              true
    use_js:               false

これで設定は完了なのですが、このままだとcssファイルがweb/cssに書きだされます。

それはいいのですが、他のcssファイルもあるところに書き込まれるのはちょっと怖いので、階層を一段下げます。

$ cd ./web/less/
$ mkdir ./bootstrap
$ mv ./*.less ./bootstrap/
$ cd ../css/
$ mkdir ./bootstrap
$ chmod 777 ./bootstrap

app/fronend/config/view.ymlを修正します。

stylesheets:    [bootstrap/bootstrap.less, main.css]

これで完了です。

レスポンシブデザインを使いたい場合は、

stylesheets:    [bootstrap/bootstrap.less, bootstrap/responsive.less, main.css]

のようにresponsive.lessを追加してあげましょう。

ちなみに生成時にsymfonyのデバッグツールバーにlessのコンパイルにかかった時間が表示されるようになります。

image

2回目以降は生成しませんが、更新の確認をするようなので、本番環境では外しておくことが推奨されています。

一度生成してしまえばあとは通常のCSSとして使えます。

config/app.ymlでprod環境を指定してcompileをfalseにします。

prod:
  sf_less_plugin:
    compile:              false
    use_js:               false

最後にタスクでの生成を確認します。

prod環境の場合はあらかじめタスクでコンパイルしてCSSにしておいたほうが便利だと思います。

初回のタスク実行前にccしておきます。

$ ./symfony cc
$ ./symfony less:compile --clean --compress

これで既存のLESSから書きだしたCSSファイルを削除して、新しく書きだされます。

一応、LESSに対応するCSSファイルしか削除しないようなので安心です。

これでcss/bootstrap/を777にしなくてよくなりますね。

–compressを付けることで容量が少し小さくなります。中身見たらこんな処理でした。

  static public function getCompressedCss($css)
  {
    return str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $css);
  }

あとは好きにbootstrapをカスタマイズできます。


HybridAuthでFacebookログインする際の権限について

HybridAuthの内部で、Facebookのscopeは

email, user_about_me, user_birthday, user_hometown, user_website, offline_access, read_stream, publish_stream, read_friendlists

がデフォルトに設定されています。scopeの設定を空にすると上記のパーミッションが使われるので、ログインに使いたいだけの場合、不要な許可をユーザーに求めることになります。

image

image

詳細なパーミッションの説明は
http://developers.facebook.com/docs/authentication/permissions/
に書かれています。

今回はFacebookをログインするためだけに使います。ここまでの情報は不要なので、Basic Information(基本データ)だけにします。基本的にはscopeを空にすれば良いはずです。

ところが、HybridAuthの内部で文字列をemptyで判断しているため、空にするとデフォルトに上書きされてしまいます。

if( isset( $this->config["scope"] ) && ! empty( $this->config["scope"] ) ){
	$this->scope = $this->config["scope"];
}

対策としては、scopeに空白をひとついれておけばOKです。

"scope"   => " ",

前回の「Symfony 1.4でHybridAuthを使ってtwitter/facebookログインを実装する」でymlにした場合は、

scope: " "

としておきます。

image

これで「このアプリが受け取る情報」の欄を減らすことができました。

ちなみに、一度許可したアプリをFacebook上から削除したい場合は

http://www.facebook.com/settings?tab=applications

から削除できます。

image


Symfony 1.4でHybridAuthを使ってtwitter/facebookログインを実装する

schema.ymlにUserモデルを以下のように作っておきます。

User:
  actAs: { Timestampable: ~ }
  tableName: users
  options:
    type: MyISAM
    collate: utf8_unicode_ci
    charset: utf8
    comment: 'ユーザー'
  columns:
    id:
      type: integer(4)
      unsigned: false
      primary: true
      autoincrement: true
      comment: 'ID'
    name:
      type: string(255)
      fixed: false
      notnull: true
      default: 'no name'
      comment: 'ユーザー名'
    image:
      type: blob
      notnull: false
      comment: 'アイコン画像'
    hybridauth_provider_name:
      type: string(20)
      fixed: false
      notnull: true
      comment: 'HybridAuthプロバイダ'
    hybridauth_provider_uid:
      type: string(255)
      fixed: false
      notnull: true
      comment: 'HybridAuthプロバイダUID'

HybridAuthをダウンロードします。

Download HybridAuth

ちなみにSymfony2用にはHybridAuthのバンドルがあります。1.4用にも欲しい…

$ cd lib/vendor
$ wget http://jaist.dl.sourceforge.net/project/hybridauth/hybridauth-2.0.11.zip
$ unzip ./hybridauth-2.0.11.zip
$ rm ./README.html
$ rm -R ./examples/
$ rm ./hybridauth-2.0.11.zip
$ cd ../..
$ mkdir lib/config

lib/configにsfEnvironmentYamlConfigHandler.class.phpを作成します。sfSimpleYamlConfigHandlerを継承して、環境設定が反映されるように変更します。

<?php

class sfEnvironmentYamlConfigHandler extends sfSimpleYamlConfigHandler
{
    public function execute($configFiles)
    {
        $config = self::getConfiguration($configFiles);
        
        // compile data
        $retval = "<?php\n".
                  "// auto-generated by %s\n".
                  "// date: %s\nreturn %s;\n";
        $retval = sprintf($retval, __CLASS__, date('Y/m/d H:i:s'), var_export($config, true));
        
        return $retval;
    }

    static public function getConfiguration(array $configFiles)
    {
        return self::replaceConstants(self::flattenConfigurationWithEnvironment(self::parseYamls($configFiles)));
    }
}

configにconfig_handlers.ymlを作成します。設定ファイルの処理の仕方をここで指定しています。

config/hybrid_auth.yml:
  class: sfEnvironmentYamlConfigHandler

で、同じくconfigにhybrid_auth.ymlファイルを作成します。

all:
  base_url: http://localhost/login/endpoint
  providers:
    OpenID:
      enabled: true

    Yahoo:
      enabled: true

    AOL:
      enabled: true

    Google:
      enabled: true
      keys:
        id: ""
        secret: ""
      scope: ""

    Facebook:
      enabled: true
      keys:
        id: ""
        secret: ""

      # A comma-separated list of permissions you want to request from the user.
      # See the Facebook docs for a full list of available permissions:
      # http://developers.facebook.com/docs/reference/api/permissions.
      scope: ""

      # The display context to show the authentication page.
      # Options are: page, popup, iframe, touch and wap.
      # Read the Facebook docs for more details:
      # http://developers.facebook.com/docs/reference/dialogs#display.
      # Default: page
      display: ""

    Twitter:
      enabled: true
      keys:
        key: ""
        secret: ""

    # windows live
    Live:
      enabled: true
      keys:
        id: ""
        secret: ""

    MySpace:
      enabled: true
      keys:
        key: ""
        secret: ""

    LinkedIn:
      enabled: true
      keys:
        key: ""
        secret: ""

    Foursquare:
      enabled: true
      keys:
        id: ""
        secret: ""

  # if you want to enable logging, set 'debug_mode' to true
  # then provide a writable file by the web server on "debug_file"
  debug_mode: false
  debug_file: ""

TwitterとFacebookのKeyとSecretにそれぞれOAuthのConsumer KeyとConsumer Secretを入れておきます。TwitterはCallback URLをダミーでも構わないので入れておかないといけないので注意。

Twitter https://dev.twitter.com/apps

Facebook https://developers.facebook.com/apps/

設定内容はHybridAuthのconfig.phpと内容的には同じものです。YAMLに書き換えたのと、devやprodなど環境ごとに設定を切り替えられるようになっています。デフォルトはall以下に書けばOKです。

lib/vendor以下はオートロードされないので、configにautoload.ymlファイルを作成します。

autoload:
  hybridauth:
    name:           hybridauth
    path:           %SF_LIB_DIR%/vendor/hybridauth
    recursive:      true

次にアクション側を実装します。

authモジュールを作ります。

$ ./symfony generate:module frontend auth

routing.ymlにログインとエンドポイントを追加します。

login_endpoint:
  url:   /login/endpoint
  param: { module: auth, action: endPoint }

login:
  url:   /login/:provider
  param: { module: auth, action: index }
  requirements:
    provider: Facebook|Google|Twitter

apps/frontend/lib/myUser.class.phpを編集してIDとユーザー名を保持できるようにします。

<?php

class myUser extends sfBasicSecurityUser
{

    const ATTRIBUTE_NAMESPACE = 'localhost/user/myUser/attributes';

    public function setName($name)
    {
        $this->setAttribute('name', $name, self::ATTRIBUTE_NAMESPACE);
    }

    public function getName()
    {
        return $this->getAttribute('name', null, self::ATTRIBUTE_NAMESPACE);
    }

    public function setId($id)
    {
        $this->setAttribute('id', $id, self::ATTRIBUTE_NAMESPACE);
    }

    public function getId()
    {
        return $this->getAttribute('id', null, self::ATTRIBUTE_NAMESPACE);
    }

    public function setImage($image)
    {
        $this->setAttribute('image', $image, self::ATTRIBUTE_NAMESPACE);
    }

    public function getImage()
    {
        return $this->getAttribute('image', null, self::ATTRIBUTE_NAMESPACE);
    }

    public function getImageBase64()
    {
        return base64_encode($this->getImage());
    }

}

lib/model/doctrine/UserTable.class.phpにプロバイダとUIDでユーザー名を検索するメソッドを実装します。

    public function getUserByProviderAndUid($providerName, $uid)
    {
        return $this->createQuery('u')
            ->where('u.hybridauth_provider_name = ?', $providerName)
            ->andWhere('u.hybridauth_provider_uid = ?', $uid)
            ->fetchOne();
    }

apps/frontend/modules/auth/actions/actions.class.phpを編集します。

<?php

class authActions extends sfActions
{

    public function executeIndex(sfWebRequest $request)
    {
        
        $config = sfContext::getInstance()->getConfigCache()->checkConfig(sfConfig::get('sf_config_dir').'/hybrid_auth.yml');
        
        try{
            $hybridauth = new Hybrid_Auth($config);
            
            $adapter = $hybridauth->authenticate($request->getParameter('provider'));
            
            $user_profile = $adapter->getUserProfile();
            
            $user = Doctrine::getTable('User')->getUserByProviderAndUid($adapter->id, $user_profile->identifier);
            
            if (!$user) {
                // 新規作成
                $user = new User();
                $user->set('name', $user_profile->displayName);
                $user->set('image', file_get_contents($user_profile->photoURL));
                $user->set('hybridauth_provider_name', $adapter->id);
                $user->set('hybridauth_provider_uid', $user_profile->identifier);
                $user->save();
            }
            
            $this->getUser()->setAuthenticated(true);
            $this->getUser()->setId($user->get('id'));
            $this->getUser()->setName($user->get('name'));
            $this->getUser()->setImage($user->get('image'));
            
            $this->redirect('@homepage');
            
        }
        catch( Exception $e ){  
            switch( $e->getCode() ){ 
            case 0 : echo "Unspecified error."; break;
            case 1 : echo "Hybriauth configuration error."; break;
            case 2 : echo "Provider not properly configured."; break;
            case 3 : echo "Unknown or disabled provider."; break;
            case 4 : echo "Missing provider application credentials."; break;
            case 5 : echo "Authentification failed. " 
            . "The user has canceled the authentication or the provider refused the connection."; 
            break;
            case 6 : echo "User profile request failed. Most likely the user is not connected "
            . "to the provider and he should authenticate again."; 
            $twitter->logout(); 
            break;
            case 7 : echo "User not connected to the provider."; 
            $twitter->logout(); 
            break;
            case 8 : echo "Provider does not support this feature."; break;
            } 
            
            // well, basically your should not display this to the end user, just give him a hint and move on..
            echo "<br /><br /><b>Original error message:</b> " . $e->getMessage();  
        }
        
        return sfView::NONE;
    }

    public function executeEndPoint(sfWebRequest $request)
    {
        Hybrid_Endpoint::process();
        
        return sfView::NONE;
    }

}

これでhttp://localhost/login/Twitterにアクセスすれば、Twitterの認証ページへジャンプしてログインができるようになります。

ログイン後のユーザー表示とかは、テンプレートでこんな感じに。

<img src="<?php echo 'data:;base64,' . $sf_user->getImageBase64(); ?>" alt="<?php echo $sf_user->getName(); ?>">&nbsp;
<?php echo $sf_user->getName(); ?>

後でどうせキャッシュしてしまうのでbase64_encodeのオーバーヘッドは無視です。


Symfony2のdoctrine2をenumに対応させる

doctrine2がenumに対応していないので、既存のデータベースからEntityを作ろうとした時にエラーが出ることがあります。

$ php app/console doctrine:mapping:convert yml ./src/Test/HogeBundle/Resources/config/doctrine/metadata/orm --from-database --force

  [Doctrine\DBAL\DBALException]
  Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.

その場合は、doctrine2のドキュメントによると、enumをstringに関連づければ良いようです。

Mysql Enums — Doctrine 2 ORM 2.1 documentation

BundleのbootでEntityManagerを取得して、マッピングを行います。

<?php

namespace Test\HogeBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class TestHogeBundle extends Bundle
{
    public function boot() {
        $em = $this->container->get('doctrine.orm.default_entity_manager');
        $conn = $em->getConnection();
        $conn->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
    }
}

他の方法として、Enumタイプを作成して関連付けることもできるようです。

※追記

app/config/config.phpに書く方法が紹介されていました。

Doctrine の DBAL レイヤーの使用方法 | Symfony2日本語ドキュメント

$container->loadFromExtension('doctrine', array(
    'dbal' => array(
        'connections' => array(
            'default' => array(
                'mapping_types' => array(
                    'enum'  => 'string',
                ),
            ),
        ),
    ),
));

試していませんが、これでもいいらしいです。


Windows版PHP 5.4.0でAPCを使う

まずはAPCをダウンロードします。

downloads.php.net/pierre/

php_apc-3.1.10-5.4-vc9-x86.zip (2012-04-11 23:46 -0700)
をダウンロードしました。

展開すると、ntsとtsのフォルダが作成されます。使っているPHPがNon Thread Safe版かThread Safe版かによって使う方を決めてください。

それぞれのフォルダの中に、php_apc.dllがあるので、phpがインストールされているフォルダのextフォルダにコピーします。

その後、php.iniを開いて
extension=php_apc.dll
を追加し、Apacheを再起動すればOKです。

ちなみに、dllのバージョンを見ると、5.4.1RC1-devと書かれていました。

phpinfo()ではこのようになります。特に問題なく使えているようです。

WS000000


sfFlickrPluginのRequest failed.に対処する

symfony 1.4にて、Flickrから画像を取得して使いたかったので、sfFlickrPluginを使ってみました。

sfFlickrPluginのインストール方法はこちらのサイトを参考にチェックアウトできます。

symfonyでFlickrを使用するためのPluginまとめ – Layer8 Reference

基本的には手動によるセットアップです。
plugins/に展開します。
自分はエクスポートしました。

$ cd plugins/
$ svn export http://svn.symfony-project.com/plugins/sfFlickrPlugin

キーに関してはさきほどのサイトを参考に。

あとは

config/ProjectConfiguration.class.php

に、enablePluginsを追加すればOKです。

  public function setup()
  {
    $this->enablePlugins('sfDoctrinePlugin');
    $this->enablePlugins('sfFlickrPlugin');
  }

で、セットアップ完了。

ここから表題の話。

グループから写真を取得したい場合はgetGroupPhotoListを使います。

が、getGroupPhotoListを実行すると、

Request failed. The requested URL returned error: 413

というエラーで停止。

plugins/sfFlickrPlugin/lib/vendor/Phlickrを最新に差し替えることで解決します。

Phlickrはこちらにあります。

Phlickr | Download Phlickr software for free at SourceForge.net

Phlickrの最新版は0.2.8だったので、丸ごと上書きします。

ファイル一式とFramework、TextUiディレクトリも上書き

それ以外のディレクトリは調べてないのでわからないですが、まぁ、置いておけば良いのでは。

Testsは、いらない雰囲気。

これで正常に動くようになりました。

あと、桁あふれの問題があるので、

PhlickrのbuildImgUrlでPhoto IDが桁あふれ : blog.loadlimit – digital matter –

を参考にして修正してください。


Symfony 1.4からZendFrameworkでPicasaWebAlbumsにアクセスする

symfony-projectのページがGoogle検索に引っかかりにくい(引っかかってもバージョン違ったりする)ので色々キーワード入れてメモ。

ZendFrameworkをSymfonyに導入する方法は以下のJobeetの17日目に書いてありました。

Practical symfony | 17日目: 検索 | symfony | Web PHP Framework

cd lib/vendor/
wget http://framework.zend.com/releases/ZendFramework-1.11.7/ZendFramework-1.11.7.zip
unzip ZendFramework-1.11.7.zip
mv ZendFramework-1.11.7/library/Zend/ .

とりあえずlib/vendorに入れておきました。

あとはconfig/ProjectConfiguration.class.phpに上記ページのコードを貼りつけて、使う直前にProjectConfiguration::registerZend();してやればOK。

Picasaの方は

Zend Framework: Documentation: Picasa Web Albums の使用法 – Zend Framework Manual

このページを参考にしてできます。

丸投げだけど日本語だしわかりやすいので特に解説も不要かな、と…


PHPでFlickrからPhlickrを使ってグループ検索

Phlickrを使って、グループIDとライセンス指定で写真を検索してくる方法です。

$api = new Phlickr_Api(API_KEY, API_SECRET);

$request = $api->createRequest('flickr.photos.search', array(
    'group_id' => GROUP_ID, // グループID
    'license' => '4,5,6', // ライセンス設定(商用利用可)
));
$photoList = new Phlickr_PhotoList($request, 500); // 1ページ500件

$pageCount = $photoList->getPageCount();
for ($i = 1 ; $i < $pageCount ; $i++) {
    $photos = $photoList->getPhotosFromPage($i);
    foreach ($photos as $photo) {
        // something nice
    }
}