

たとえば`PHP`の処理を実行したい時、ブラウザを開いて毎回結果を確認しています。  
`$ php -f
file.php`で実行できるのは知っているのですが、getリクエストなどのパラメータが渡せないと確認できなかったりするので、結局ブラウザでの確認をしてしまいます。

また、rubyなどでも`ruby on
rails`などのウェブフレームワークになると、コントローラのアクションを指定して実行することになるので、やはりgetリクエストなどが必要になってしまいます。

皆さんはこれをどう解決しているのでしょうか?


CC BY-SA 3.0
2015-02-05T23:05:56.340
6028
2015-02-06T01:48:05.447
5855
question
ruby php ruby-on-rails
プログラムをコンソールから実行する時


なぜブラウザから確認するのはダメなのか？  
なぜコンソールから画面側の処理を実行しようとするのか、その理由がよくわかりません。  
Railsの開発は結構長くやっていますが、僕の場合そういうニーズを感じたことはないです。

そのあたりがわからないと何とも言えないのですが、「ブラウザ以外の場所から画面の処理を実行したい」という場合、Railsであれば「テストから実行する」という方法があります。

たとえばRSpecを例にとると、フィーチャスペックという種類のテストを書けば、Rubyからブラウザ操作をシミュレートすることができます。  
デバッガと組み合わせれば、テスト実行中に変数の中身を確認したりすることも可能です。

フィーチャスペックに関しては以前Qiitaにこんな記事を書いたことがあるので参考にしてみてください。

[使えるRSpec入門・その4「どんなブラウザ操作も自由自在！逆引きCapybara大辞典」](http://qiita.com/jnchito/items/607f956263c38a5fec24)

「いや、自分のやりたいことはそうじゃないんだけど」という場合は、やりたいことは何でどういうところに困っているのかをもう少し詳しく説明してください。

### 追伸

僕は滅多にやりませんが、`rails console`からgetリクエストやpostリクエストを実行する方法もあります。  
詳しくは以下のweb記事を参考にしてみてください。

  * [How do I call controller/view methods from the console in Rails?](https://stackoverflow.com/questions/151030/how-do-i-call-controller-view-methods-from-the-console-in-rails)
  * [rails console から アプリケーションに対して GET や POST リクエストを発行して調査するには](http://qiita.com/hyone/items/cd79c309f9e6077f0d68)


CC BY-SA 3.0
2015-02-06T00:37:44.140
6029
2015-02-06T00:44:08.600
2017-05-23T12:38:55.307
-1
85
6028
answer


railsであれば、`rails console`からリクエストを投げることができます。getとpostの例です。CSRFのトークンの取得は[英語版の質問
"How do I generate a CSRF token from the Rails
console?"](https://stackoverflow.com/questions/23922059/how-do-i-generate-a-
csrf-token-from-the-rails-console)を参照しました。

[code]

    irb(main):011:0> app.get '/items/new'
    
    
    Started GET "/items/new" for 127.0.0.1 at 2015-02-06 09:45:48 +0900
    Processing by ItemsController#new as HTML
      Rendered items/_form.html.erb (2.2ms)
      Rendered items/new.html.erb within layouts/application (4.6ms)
    Completed 200 OK in 91ms (Views: 89.7ms | ActiveRecord: 0.0ms)
    => 200
    irb(main):012:0> authenticity_token = app.response.body.match(/<[^<]+authenticity_token[^>]+value="([^"]+)"[^>]+>/)[1]
    => "Xt0BiLJMRo3Y2Vpd4KVUK87xcK2UFDvHvFv9Dcf/G5EKSof4udaiwqYOH/3PRld+nStCp6Z5Sn+NA7+albNltw=="
    irb(main):013:0> app.post '/items', {'item[name]': 'hoge', authenticity_token: authenticity_token}
    
    
    Started POST "/items" for 127.0.0.1 at 2015-02-06 09:46:07 +0900
    Processing by ItemsController#create as HTML
      Parameters: {"item"=>{"name"=>"hoge"}, "authenticity_token"=>"Xt0BiLJMRo3Y2Vpd4KVUK87xcK2UFDvHvFv9Dcf/G5EKSof4udaiwqYOH/3PRld+nStCp6Z5Sn+NA7+albNltw=="}
       (0.2ms)  begin transaction
      SQL (1.1ms)  INSERT INTO "items" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "hoge"], ["created_at", "2015-02-06 00:46:07.998190"], ["updated_at", "2015-02-06 00:46:07.998190"]]
       (6.9ms)  commit transaction
    Redirected to http://www.example.com/items/1
    Completed 302 Found in 18ms (ActiveRecord: 8.2ms)
    => 302
    
[/code]


CC BY-SA 3.0
2015-02-06T00:51:15.160
6031
2015-02-06T01:11:38.037
2017-05-23T12:38:55.307
-1
5793
6028
answer


PHPでは、以下の2つの方法が思いつきました。外部ライブラリは未使用です。  
尚、以下の適当なファイル(test.php)を用意して確認しています。

[code]

    <?php
    
    var_dump($_GET);
    
[/code]

**1.コンソールからparse_str()で$_GET等を上書きする方法**  
コンソールから次のコマンドを実行します。

[code]

    $ QUERY_STRING="xxx=yyy&zzz=aaa" php -r 'parse_str(getenv("QUERY_STRING"), $_GET); include("test.php");';
    
[/code]

結果は以下の通りです。

[code]

    array(2) {
      'xxx' =>
      string(3) "yyy"
      'zzz' =>
      string(3) "aaa"
    }
    
[/code]

参考:  
<https://stackoverflow.com/questions/3848901/how-to-pass-query-string-
parameters-to-the-php-binary>

**2. ビルトインウェブサーバーを使う方法**  
前述の"test.php"が有る場所でビルトインウェブサーバーを起動します。

[code]

    $ php -S localhost:8000
    
[/code]

何らかの方法でアクセスします。以下は適当な一つの例です。

[code]

    $ php -r "echo file_get_contents('http://localhost:8000/test.php?foo=bar&baz=qux');"
    
[/code]

この結果は以下です。

[code]

    <pre class='xdebug-var-dump' dir='ltr'>
    <b>array</b> <i>(size=2)</i>
      'foo' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'bar'</font> <i>(length=3)</i>
      'baz' <font color='#888a85'>=&gt;</font> <small>string</small> <font color='#cc0000'>'qux'</font> <i>(length=3)</i>
    
[/code]

ビルトインウェブサーバーを起動したコンソール側には、以下のような出力がされているはずです。

[code]

    [Fri Feb  6 09:54:28 2015] ::1:51546 [200]: /test.php?foo=bar&baz=qux
    
[/code]

**3. その他**  
Goutte等の外部ライブラリを使えば、より高度な実行が可能です。  
<https://github.com/FriendsOfPHP/Goutte>


CC BY-SA 3.0
2015-02-06T01:08:40.267
6034
2015-02-06T01:13:54.787
2017-05-23T12:38:55.250
-1
589
6028
answer


確認したい部分にもよりますが、GetやPostのパラメータを直に取り出しているから確認できないのであれば、それはそれらに依存しているという事であり、関数やクラスに分離するサインと受け取ることもできます。

依存を分離すれば別の起動処理を用意してコンソールから実行できる可能性も高まります。

（要するに単体テストみたいなものなので他の回答でもあがっているようにテストフレームワークに任せるのがいいですが、ここで述べるのはそこまでするのが大げさな場合の話とします。）

極端な例ですが、以下のコードはGETパラメータを必要とします。

  * index.php

[code]

    <?php
    $name = htmlspecialchars($_GET['name']);
    echo <<<EOHTML
    <html><head></head>
    <body>
    {$name}!!!<br>
    </body></html>
    EOHTML;
    
[/code]

(依存ぶりを表現するために、$_GETをベタにヒアドキュメントに埋め込もうかとおもったんですがさすがに脆弱にもほどがあるのでやめました。)

これを以下の様に分離して２つに分けます。

  * index.php

[code]

    <?php
    require_once('template.php');
    show_greeting_page($_GET['name']); // issetなどは簡単のため割愛
    
[/code]

  * template.php

[code]

    <?php
    function show_greeting_page($name){
        $name = htmlspecialchars($name);
        echo <<<EOHTML
        <html><head></head>
        <body>
        {$name}!!!<br>
        </body></html>
        EOHTML;
    }
    
[/code]

これにより、本処理はGETパラメータを必要としなくなったので、コンソールで確認したい場合は以下の様なファイルを用意してこちらを実行すればいいでしょう。

  * inspect_template.php

[code]

    <?php
    require_once('template.php');
    show_greeting_page('hello <taro>');
    
[/code]

以下が実行イメージ。

[code]

    [ ~/somedir/]$ php -f inspect_template.php
        <html><head></head>
        <body>
        Hello &lt;taro&gt;!!!
        </body>
        </html>[ ~/somedir/]$
    
[/code]

上記は依存の分離と呼ぶほどのものではありませんが、なるべく外に依存しないパーツに分離しておけば確認の方法は増えると思います。

Webフレームワークの機能や複雑なオブジェクトに依存していて、単純には状態を再現できない箇所の確認をしたい場合は  
フレームワーク用のテスト機能やブラウザを自動操作するツールに頼れば良いと思います。


CC BY-SA 3.0
2015-02-06T01:48:05.447
6036
2015-02-06T01:48:05.447
728
6028
answer