laradock で プロファイラ（性能解析）ツール xhprof を入れて動かす

php を使っている環境で、プロファイラツールというと xhprof が有名なようですが、laradock 環境で簡単に使えないかな？ と思って調べて記録です。

tideways/xhprofの公式レポジトリ: https://github.com/tideways/php-xhprof-extension
可視化のためのツール: https://github.com/sters/xhprof-html

どうも調べてみるとlaradockのgithubレポジトリに `xhprof.ini` ファイルがあることがわかりました。
https://github.com/laradock/laradock/blob/master/php-fpm/xhprof.ini


## インストール方法

```laradock/.env
PHP_FPM_INSTALL_XHPROF=true
```

これを有効にして、再度ビルド。

```shell
$ docker-compose build php-fpm
```

## コードでの利用法

```php

tideways_enable();

your_code();         

file_put_contents(
    '/tmp/offer_search.xhprof',
     json_encode(tideways_disable())
);
```

※公式で書いてあるメソッド名（`tideways_xhprof_enable()`）と違うこれで動く
情報提供のブログ（中国語）　https://translate.google.com/translate?hl=ja&sl=zh-CN&u=https://blog.mango.im/2018/05/php-xhprof-extension-01/&prev=search

これは、laradockでインストールしている tideways のバージョンが 4.1.7 であるのに対して、
tideways の最新のバージョンが5系になっているからだった。
laradockファイル該当箇所： https://github.com/laradock/laradock/blob/04c6aaf3389ebd30e2874788b90437f229effb0b/php-fpm/Dockerfile#L275


追記： 修正PRを出したので**最新版のLaradockだと動くはず**　https://github.com/laradock/laradock/pull/2342


## 見る
おまけです。色々なみるためのソリューションがあるのですが、私が試した方法だけ記録しておきます。

#### 直接ファイルみる
php-fpm のコンテナに入って、 `/tmp/`ディレクトリにいくと該当ファイルがあるので、ダウンロードするなりコピーするなりして中身見れます。
json なので jq で見るなり `http://jsonviewer.stack.hu/` こういうので見るなりできます。


#### xhprof-htmlでみる

こちらを使います。https://github.com/sters/xhprof-html
使い方は公式に書いてある通り単純です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/1485d9d5-4e24-c7c0-5f38-fa58f8b2f365.png)

ただし、いくつかハマりどころがあったので記録しておきます。
ツールのclone先をプロジェクト直下の `/public/` 下とすると、laradockのphp-fpmコンテナの中では `/var/www/public/xhprof-html/` になります。ここに結果出力先を `output` を作っておくとして （`$ mkdir output`） 出力結果の出し方は以下のようになります

```php

tideways_xhprof_enable();

my_application();

$data = tideways_xhprof_disable();
// ★出力先に注意
$filename = '/var/www/public/xhprof-html/output/' . intval(microtime(true)) . mt_rand(1,10000) . '.xhprof';
// ★serialize していることに注意。
file_put_contents($filename, serialize($data));
```

ファイルを直接みるときには serialize いらないのですが、このツールを使うときには必要です。

で、クローンしたツールのレポジトリのディレクトリ内で`php -S`でサーバ起動します。このPHPはMacのPC内のphpコマンドを用います。

上記のコードでアウトプット先を決めたところをURLのクエリパラメタで追加してリクエストします。
`http://localhost:8000/?dir=/Users/MyUserName/PathToProject/public/xhprof-html/output`

ここまではドキュメントに書いてある通りなのですが、最後にハマりどころがありました。出力ファイル名でそのまま読んでくれないで
`/Users/MyUserName/PathToProject/public/xhprof-html/output/15733478965982.xhprof.xhprof` のように拡張子が二つついているような状態のファイルを期待したコードになっていました
今の所、こういうコードになっている詳細未調査。$type と $suffix がそれぞれ対応しており、$type になんでか xhprof が入ってくる（グローバル変数登録をどこかでしている？）。
それはそうと、とりあえず以下のように直せば治りました。（こちらも時間見つけてコミットしたい・・・）

```
--- a/xhprof_lib/utils/xhprof_runs.php
+++ b/xhprof_lib/utils/xhprof_runs.php
@@ -76,7 +76,8 @@ class XHProfRuns_Default implements iXHProfRuns {

   private function file_name($run_id, $type) {

-    $file = "$run_id.$type." . $this->suffix;
+    $file = "$run_id." . $this->suffix;

     if (!empty($this->dir)) {
       $file = $this->dir . "/" . $file;
```


というわけで最終的にブラウザアクセスすると

こういう感じとか（アクセスごとに結果がみれる）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/2f8cf9b0-7734-3db8-c2b6-104a7e157cd0.png)

こういう感じで（詳細のメソッドを追っていくと、それがどれくらい呼ばれてて、実時間Wall Timeでどれくらいかかっているかわかります。）
※プロジェクトに多少関係があるところはモザイク入れてあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/31ad2544-ceac-c305-87de-178932391630.png)