Visaul Studio Code で PHP、インテリセンスとデバッグ

#Visual Studio Code で PHP、ついでにPHPDebugの設定も。

Windows 10 Pro
Hyper-V Ubuntu 16.04
Visual Studio Code 1.17.2


PHPのIDEといえばPHPStorm一択かなと思ってますがライセンスが切れ以来更新してません。
何しろPHP自体が数年に数日しか使わない頻度なので費用が惜しくてVisual Studio Code使うことにしました。
WordPressのテーマとプラグイン作りたいだけなんですよね。

特に拡張機能をインストールしなくてもデフォルトで多少の補完位は行ってくれますが、そのままでは使いにくいので拡張機能をインストールします。
とりあえず試した拡張機能は以下の通り、うち上位２つがあれば事足りるようです。

| 拡張機能 | 要約 |
|:--|:--|
| PHP Intellisense | インテリセンス。コード補完やコード修正(若干難あり)など。 |
| PHP Debug | XDebugを使ったデバッグ。 |
| phpcs | コーディング規約のチェック |

PHP Formatterは動かせなかったので諦めました。




## デフォルト

デフォルトで.phpファイルを編集すれば最低限のコード補完やハイライトが使えます。


### SQLのハイライト

![vsc-phpintelli-sql.png](https://qiita-image-store.s3.amazonaws.com/0/205767/f851bb64-cbad-9de5-25ab-1bac5bfb512c.png)


少しびっくりなのがSQLがハイライトされる点。
どうやらSELECTで始まる文字列はSQLでハイライトされるみたいです。





## インテリセンス(コードの補完)を使う



![vsc-codeintelli.png](https://qiita-image-store.s3.amazonaws.com/0/205767/4fb04ad0-0ef7-c3f2-8f2f-48aa8c13c856.png)


PHP IntelliSense

https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense

![vsc-php-intelli.png](https://qiita-image-store.s3.amazonaws.com/0/205767/d1c3ceb6-5bea-98d7-d5be-28b46e1f9b02.png)




見た感じ一番使われてそうなのでこれを使います。
丸の目印をクリック、phpで検索をかけるとPHP用の拡張機能が表示されます。
似たような名前の拡張機能がいくつかあるので注意してください。


### 注意点

PHPを書く時って面倒だから

    <?

って書いてました。これだと思ったようにインテリセンスが効きませんでした。

    <?php

って書いたら効きました。






### 型情報をアノテーションで補完

PHP等のスクリプト言語で一番面倒くさいのが型なんですよね。
もしかしてと思ってアノテーション使ってみたら、


```php
class Sample1
{

    private $pdo1;

    /**
     * @var PDO
     */
    public $pdo2;

    function __construct()
    {
        $this->pdo1 = new PDO;
        $this->pdo2 = new PDO;
    }

    public function method()
    {
        $this->pdo1->prepare(); // 補完が効かない。
        $this->pdo2->prepare(); // 補完が効いた！！！
    }
}

class Sample2
{

    public function getPdo1()
    {
        return new PDO;
    }

    /**
     * @return PDO
     */
    public function getPdo2()
    {
        return new PDO;
    }

    public function method()
    {
        $p1 = $this->getPdo1();
        $p2 = $this->getPdo2();
        
        $p1->prepare(); // 補完が効かない
        $p2->prepare(); // 補完が聞いた！！！
    }
}

class Sample3
{

    public function method1($pdo)
    {
        $pdo->prepare(); // 効かない
    }

    /**
     * @param PDO $pdo
     */
    public function method2($pdo)
    {
        $pdo->prepare(); // 効いた
    }

    public function method3(PDO $pdo)
    {
        $pdo->prepare(); // 効いた
    }
}
```

あくまでハイライト・インテリセンスの実験なのでコードは適当です。

おぉ、アノテーション付けたらインテリセンス効いた。
興味ある人はPHPDocとかでググってみてください。

**ただし、PDOで実験した限りでは自動保存(ファイル→自動保存)を有効にしてないと効かなかった、というよりカーソルを合わせるまで候補が出ないという。バグ？**



| アノテーション | 意味 |
|:--|:--|
| @var | 変数やプロパティにつける、変数やプロパティの型を表す |
| @param | メソッドにつける、引数の型表す |
| @return | メソッドにつける、戻り値の型を表す |



### 機能一覧

右クリックで現れるコンテキストメニュー。

| メニュー | 意味 |
|:--|:--|
| 定義へ移動 | 変数や関数などの呼び出し側で右クリック、定義してある場所へ飛びます |
| 定義をここに表示 | 「定義へ移動」の移動はせず、その場にインライン表示します |
| すべての参照の検索 | 変数や関数の定義側で右クリック、呼び出し側一覧を検索 |
| ドキュメントのフォーマット | エディタ上で右クリック、ドキュメントのフォーマットでコードを修正 |

簡単に説明すると、「えーと、この関数ってどこから呼び出されているんだろう(複数あり)！」とか、「この変数、どこで定義されているんだろう」などを知りたいとき使用します。
フォーマットは、汚ったないコードをある程度修正してくれます(多分思い通りにはいかない)。




### 保存時にフォーマット

ファイルの保存時に自動的にフォーマットすることも出来ます。
ただし、この設定は他の拡張機能の動作に影響が及ぶかもしれません(未確認)

![vsc-phpintelli-onsave.png](https://qiita-image-store.s3.amazonaws.com/0/205767/24852f49-fc75-0ea1-f9df-9130d523e4a0.png)


ファイル→基本設定→設定

で適当に「format」などで検索をかけて


editor.formatOnSaveを編集します。
鉛筆をクリックしてtrueを選択すると右側の画面に設定が追加されます。



## デバッグする。

デバッグって？
今時var_dump()とかしている人ならぜひ使ってください。

実行中のプログラムを途中で止めて(ブレークポイントという目印を張った場所)、その時点での変数の値などをチェック出来ます。
あっちこっちにvar_dump()を貼っては剥がし、貼っては剥がし、時には剥がし忘れ、なんてひたすら手間のかかる作業から解放されます。


まずはPHP側でXDebugに対応します。




### PHPにXDebugを追加。

既にPHP7.0をインストールしていることが前提です。
XDebugをインストールします(既にインストールしていたら不要)
XDebugはPHPでデバッグをするための拡張機能です。

    sudo apt install php-xdebug

↑XDebugをインストールします。


    sudo vi /etc/php/7.0/mods-available/xdebug.ini

↑XDebugの設定ファイルを編集します。


```ini
zend_extension=xdebug.so
; ↑これは元々あったやつ

; ↓これを追加
xdebug.remote_enable=1
xdebug.remote_autostart=1
```

    sudo service apache2 restart

ウェブ用のPHPを使う人はApache再起動。


とりあえず最低限の設定ファイルを編集します。
XDebugの使用するポートはデフォルトで9000になってるので「xdebug.port=9000」は省きました。

このファイルは/etc/php/7.0/apache2/conf.d/20-xdebug.iniや/etc/php/7.0/cli/conf.d.20-xdebug.iniなどからリンクされてます。



xdebug.remote_autostart=1
はXDebugの自動開始を有効にしてます。

> xdebug.remote_autostartの機能。
>> 自動があるということは手動もあります。
>> 昔使ったことありますが詳細は忘れました。間違ってる可能性もあります。
>> \$_GET \$_POST \$_COOKIE にXDEBUG_SESSIONを込めてアクセスすることで手動操作出来たと思います。
>>
>> https://www.jetbrains.com/phpstorm/marklets/
>>
>> 例えばPHPStormのサイトでばブックマークレットを使ってクッキーにXDEBUG_SESSIONを埋め込む仕組みを用意してます。
>> 後はお気に入りにでも入れればって感じの使い方です。他にGETで投げるとか。
>> 今回は使わないんですけどね。



### Visual Studio CodeにPHP Debug追加


次はVisual Studio Code側


続いて、拡張機能から「PHP Debug」をインストールします。


![vsc-dbgconf.png](https://qiita-image-store.s3.amazonaws.com/0/205767/9f6c12d0-df25-da63-c82f-2a80e5875199.png)


丸印のデバッグ(虫)のアイコンから四角の設定ファイル(launch.json)を開きます。
初回設定はテンプレートのリストから「PHP」を選択すればいいんですが、既にlaunch.jsonが存在するとファイルが直接開かれるだけなので自分で追加します(この辺使いにくいなー)。


```json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000
        }
    ]
}

```

デバッグはCLI用とウェブ用があります。

    Listen for XDebug

↑ウェブ用でデバッグします。

    Launch currently open script

↑CLI用でデバッグします。

CLI用にportいらなくね！？
programの設定をしているとCLIで動くということでしょうか。
設定の内容はまだ調べきれてません。

https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug

こちらに書いてあります。


CLI用だとApache停止していても動きます。



### Visual Studio Code PHP Debug でデバッグ


![vsc-intelli-breakpoint1.png](https://qiita-image-store.s3.amazonaws.com/0/205767/386616be-c336-969e-745c-a15888023d66.png)


適当にコードを書いて、行番号の左側をクリックすると赤い丸がポツンと付きます(クリックすると今度は外れる)。
この赤丸をブレークポイントといいます。気になるところにブレークポイントを張っていきます。


```php
$brk = 5;

for( $i=1; $i<=10; $i++ )
{
    echo "Hello World!\n";

    if( $i == $brk ){
        echo "Break : {$i}\n";
        break;
    }
}
```

次にLaunch...のCLI用のデバッグを選択してから、緑の三角ぼたんを押します。
デバッグを開始します。

![vsc-intelli-breakpoint-2.png](https://qiita-image-store.s3.amazonaws.com/0/205767/a8758416-3fed-f17c-0729-3ed46054e637.png)


貼ったブレークポイントの場所でコードが停止します(してなかったら失敗)。

デバッグコンソールでこれまでの出力が表示されてますし、変数にカーソルを充てると値が表示されます。
次のブレークポイントに移動したり、停止したりのデバッグ操作が出来ます。


今度はウェブ用です。四角ボタンを押して一旦デバッグを停止してください。



今度はウェブ用でデバッグします。
Listen for XDebugに変更してデバッグを開始。


![vsc-debug-breakpointweb.png](https://qiita-image-store.s3.amazonaws.com/0/205767/be46f98f-0f13-b56e-c878-48db19a234e5.png)


次にブラウザで対象のPHPページを開くとブレークポイントで止まります(止まらないと失敗)。



**失敗したと思ったら・・・。**

例えばサーバ側のディレクトリと、VSCの作業ディレクトリが違うと失敗します。
この場合はlocalSourceRootとserverSourceRootを設定します。

```json
{
    "name": "Listen for XDebug",
    "type": "php",
    "request": "launch",
    "localSourceRoot": "${workspaceRoot}",
    "serverSourceRoot": "/var/www/html",
    "port": 9000
}
```

localSourceRootでVSCの作業ディレクトリ、
serverSourceRootでサーバー側のディレクトリ。

${workspaceRoot}はVSCの作業ディレクトリ。


**もしサーバ(XDebug)とクライアント(VSC PHP Debug)が別だったら。**

リモートでアクセスします。
XDebugの設定にxdebug.remote_hostを追加します。

```ini
zend_extension=xdebug.so

xdebug.remote_enable=1
xdebug.remote_autostart=1

xdebug.remote_host=192.168.1.11
```

    sudo service apache2 restart


xdebug.remote_hostにクライアント側のIPアドレスを設定します。
環境に合わせてください。

**リモートの場合はクライアント側がポートを開いておかないとアクセスできません。**

クライアントがUbuntuだったら

    sudo ufw allow 9000

ポートはXDebugの設定(デフォルトは9000)に合わせます。
Windowsでも設定します。方法はググってください。

以前、Windowsで使っていてこの件でハマりました。







## コーディング規約チェック

https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs
拡張機能からphpcsをインストールしてVSCを再起動します。
調べ切れてませんが、拡張機能では修正まではしてくれないのかな？


https://qiita.com/ukyooo/items/c1c7d12ec8e11f33139b
phpcsについて書かれてます。





    phpcs: Unable to locate phpcs. Please add phpcs to your global path or use composer depency manager to install it in your project locally.

名前が同じなので紛らわしいですが、ライブラリのほうのphpcsをインストールしている必要があるようです。
phpcsをグローバルパスかComposerって


Composerの場合

    composer global require "squizlabs/php_codesniffer=*"


https://github.com/squizlabs/PHP_CodeSniffer
composer使わない場合は上記を参考にしてください。



さて、使えると思っていたら、




    phpcs unexpected token P in JSON at position 0

えーと、


https://github.com/ikappas/vscode-phpcs/issues/32

ググったらphp-xmlインストールしてないからだった。

    sudo apt install php-xml
    sudo service apache2 restart

でエラーは消えました。

![phpcs.png](https://qiita-image-store.s3.amazonaws.com/0/205767/812f1402-be25-6c68-6967-43b3a505443e.png)


あー、こういうことですか。

プログラミングは趣味でやってるだけだし、PHP自体ほとんど使わないし、

言い訳|・`) そーっと無効にしておこう・・・。


他にもいろんな拡張機能ありそうだけどひとまずこれでよし。
後、WPのためにプロフイラなどは使わないのでそのへんはやめておきます。