こんにちは!下田です。

ところでPHPerの皆様!PsySH使ってますでしょうか!

手元でちょっとしたスクリプトを書いて動かしたり、Nagoya.phpで出題される「どう書く」問題のお供に使ったり、何かと便利なやつです。

詳しい説明は公式ページに譲るとして、今日はPsySHをSymfonyで使う際のちょっとしたtipsを共有します。

インストール

Symfony2系の頃からあるPsyshBundleなんてのもありますが、僕はいつも素のままでcomposer requireしています。

$ composer require --dev psy/psysh

新規プロジェクトをgit cloneした直後など、思考停止で即インストールしてます。

ブレークポイントとして使う例

ローカル開発で特に捗るのですが、処理の途中でeval(\Psy\sh());と書くと、そこで処理が停止してコンソールが開きます。

例えばこんなスクリプトを書いて(中身は適当)

<?php

require __DIR__.'/vendor/autoload.php';

$zipped = array_map(null, [1,2,3], ['a','b','c'], ['foo','bar','baz']);

eval(\Psy\sh());

実行してみましょう。

% php test.php

Psy Shell v0.9.12 (PHP 7.3.12 — cli) by Justin Hileman

From test.php:7:

    5| $zipped = array_map(null, [1,2,3], ['a','b','c'], ['foo','bar','baz']);
    6|
  > 7| eval(\Psy\sh());
    8|
>>> 

ここで入力待ち状態になります。 $zippedの中身を見てみましょう。

>>> $zipped
=> [
     [
       1,
       "a",
       "foo",
     ],
     [
       2,
       "b",
       "bar",
     ],
     [
       3,
       "c",
       "baz",
     ],
   ]
>>> 

わーい!完璧ですね。

Symfonyで使ってみる

こんな調子で、ローカルでのSymfony開発にも使ってみましょう。

試しにRequestオブジェクトの中身を見てみたいと思います。

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class FooController extends AbstractController
{
    public function fooAction(Request $request): Response
    {
        eval(\Psy\sh());
        // ...
    }
}

おもむろにサーバを起動し、

% symfony server:start

ブラウザでfooActionにアクセスした後、コンソールに戻って見てみます。

|WARN | PHP    child 9777 said into stdout: "Psy Shell v0.9.12 (PHP 7.3.12 — fpm-fcgi) by Justin Hileman"
|WARN | PHP    child 9777 said into stdout: ""
|WARN | PHP    child 9777 said into stdout: "From /your/project/src/Controller/FooController.php:18:"
|WARN | PHP    child 9777 said into stdout: ""
|WARN | PHP    child 9777 said into stdout: "    16|     public function fooAction(Request $request): Response"
|WARN | PHP    child 9777 said into stdout: "    17|     {"
|WARN | PHP    child 9777 said into stdout: "  > 18|         eval(\Psy\sh());"
|WARN | PHP    child 9777 said into stdout: ""
|WARN | PHP    child 9777 said into stdout: "Exit:  Ctrl+D"

おや。入力待ちにならずにスルーされてしまいました。

どうやらsymfonyコマンドでサーバを起動すると、プロセスをフォークした先の子プロセス側でpsyshが発動してしまうらしく、うまく止まってくれません。

そこでちょっと工夫

実は、symfonyコマンドを使わずとも、PHPのビルトインサーバを直接使ってsymfonyを起動することができます。

バージョン4系なら以下です。

% php -S 127.0.0.1:8000 public/index.php
Psy Shell v0.9.12 (PHP 7.3.12 — cli-server) by Justin Hileman

From /your/project/src/Controller/FooController.php:18


    16|     public function fooAction(Request $request): Response
    17|     {
  > 18|         eval(\Psy\sh());
    19|
>>>

やった!捗りますね。

SymfonyはProfilerが強力なので、もともとデバッグしやすい類のFWだと思いますが、

こういったツールを使うことで処理の流れやコードリーディングなどの際にも役に立つかもしれませんね。