unoh.github.com

symfonyのsfBrowserを使ってコンソールツールを作成してみました

Wed Jul 28 22:46:35 -0700 2010

はじめまして、4月に入社しました、はなだと申します。
以後よろしくお願いいたします。


私自身は、これまでにJava/C#/C++/Perlなどを使った開発を行って来ましたが、現在は(はじめての!)PHPを使ったソーシャルアプリの開発を行っています。
これまでは、新しい言語を学習する際に、サンプルやチュートリアルを終えたあとで、ちょっとした作業を簡略化するためのツールをチョコチョコとつくっていました。今回は、はじめてのPHPということで、symfonysfBrowserを使った、コンソールツールを作ってみました。

このツール開発を通じてやりたいことは次のような内容です。

さらに 

というものがありました。

ところで、携帯電話対応のWebアプリに対する動作確認を行う場合には、FireMobileSimulatorを使うのが一般的だと思いますが、2台以上の携帯電話で相互に影響を及ぼす機能を確認する際には、いちいち端末を切り替えるよりも、コンソールからお手軽にリンクをクリックさせたいと思ったのが作成動機です。

コードは以下のようになります。

<?php
// ツールの初期化関数
function initialize()
{
    // symfonyプロジェクトの設定情報を読み込む
    require_once dirname(__FILE__).'/config/ProjectConfiguration.class.php';
    // アプリ名と環境を指定して設定情報を取得
    $configuration = ProjectConfiguration::getApplicationConfiguration('アプリ名', 'test', true);
    // コンテキストを作成
    sfContext::createInstance($configuration);
    // remove all cache
    sfToolkit::clearDirectory(sfConfig::get('sf_app_cache_dir'));

    // sfBrowserインスタンスを作成
    $browser = new sfBrowser();
    // 必要であれば携帯電話のUser-Agentと固有IDを設定
    $browser
        ->setHttpHeader('User-Agent', 'DoCoMo/2.0 N02A(c100;TB;W24H16)')
        ->setHttpHeader('X-DCMGUID', '携帯電話の固有ID');
    return $browser;
}

// sfBrowserインスタンスとURLを指定して、anchorのリストを表示
function process($browser, $url)
{
    echo "Url: [$url] \n";
    // セレクタ取得
    $selector = $browser->get($url)->getResponseDomCssSelector();
    echo 'Title: ' . $browser->getResponse()->getTitle() . "\n";
    // aタグノードの一覧を取得
    $anchors = $selector->matchAll('a')->nodes;
    foreach($anchors as $key=>$anchor) {
        echo "$key: " . $anchor->nodeValue . "\n";
    }
    echo "q:quit, 0-:click link\n> ";
    return $anchors;
}

function main($url)
{
    $browser = initialize();
    // 標準入力をopen
    $fp = fopen('php://stdin', 'r');
    if (!$fp) {
        exit("Failed to open STDIN\n");
    }

    // ループを回す
    while(!feof($fp)) {
        $anchors = process($browser, $url);
        $command = fgets($fp, 256);
        $command = trim($command);
        if ($command === 'q') {
            // コマンドが'q'の場合には終了
            break;
        } else if (is_numeric($command)) {
            // コマンドが数字の場合にはanchorの配列から取得
            $index = intval($command);
            if ($index < count($anchors)) {
                // href属性からURLを取得
                $url = $anchors[$index]->getAttribute('href');
            } else {
                echo "Out of range. [$index]\n";
            }
        } else {
            echo "Unknown command. [$command]\n";
        }
    }
    fclose($fp);
    echo("\nQuit.\n");
}

if ($argc < 2) {
    exit("Usage:>php $argv[0] [url]\n");
}
main($argv[1]);
?>

例えばこれをsymfonyのプロジェクトルートディレクトリ直下にConsoleBrowser.phpという名前で保存します。
ルートパス(/)をオープンするには、次のようなコマンドを実行します。

$ cd myprj
$ php ConsoleBrowser.php /

"q"コマンドでツールを終了できます。読み込んだコンテンツにaタグ(anchor)がある場合には、数字付きリストで表示されるので、その番号を入力すれば、リンク先に遷移します。

基本的な実装しかしておりませんので、formタグに対応させる、内容を表示させる、postで送信する、パラメータの入力を行う、などの拡張は皆様の手で是非とも追加してみてください。