【要注意】WordPressでのcomposerパッケージコンフリクト
「wordpressのプラグインを作ってアップロード。」
「あれ、ローカルで動いたのに本番環境では意味わからないエラー出てる。」
「しかも、エラーログはパッケージ内を指している。」
こんな状況でとても苦労したので、メモしておきます。
原因
なぜ、エラーログがパッケージ内を指しているかというと他のテーマやプラグインでも同じパッケージを使用しているからです。
今回自分がハマった例では
- テーマ google/apiclient
- プラグイン guzzlehttp/guzzle scotteh/php-dom-wrapper
というパターンです。
google/apiclient内でguzzleを使用しているため、先に読み込まれるプラグインは正常ですが、テーマ側で読み込まれる関数の方にエラーが発生していました。
エラー文直接検索にかけたところ「guzzleの異なるバージョンが読み込まれると致命的エラーが発生する」とのことです。
解決
調べたところ「php-scoper」を使用して自動でパッケージ群に対して名前空間を付与していくことでエラー回避が出来るみたい。
githubページ: humbug/php-scoper
composer global require humbug/php-scoper
グローバルにインストール。
私の場合上記でエラーが出たので下記の方法でインストールしました。
composer require --dev bamarni/composer-bin-plugincomposer bin php-scoper config minimum-stability devcomposer bin php-scoper config prefer-stable truecomposer bin php-scoper require --dev humbug/php-scoper
インストールしたら後は簡単以下コマンドで名前空間を固有化してくれます。
php-scoper add-prefix
php-scoperが定義されていませんと出る場合は
- /vendor/bin でパスを通す
- cmd一回閉じる
- 再度 「php-scoper add-prefix」
で試してください。
少し経つと[yes/no]と出るのでyes(初回デフォルト)を選択して継続します。
プログレスバーが表示されて書き換えが始まります。(パッケージ数にもよると思いますが、少々時間がかかります。)
書き換えが終了すると「vendor」と同階層に「build」というフォルダが作成されています。
この中が実際に書き換えられたものになります。
中身を見てみると自動で振られた固有値が確認できると思います。
最後にautoloadの書き換えです。
buildフォルダに入り
composer dump-autoload
を叩けば完成。
wordpressのプラグインであれば「build」フォルダをzip化してあげればOKです。
※WP_Queryなど記述している場合は少し注意
phpの関数はすべてバックスラッシュが振られますが、「new WP_Query()」など記述している場合はバックスラッシュが振られません。
スコープの関係でおそらくエラーが出ます。
「new \WP_Query()」などとあらかじめ変更しておきましょう。
または、「scoper.inc.php」で設定しておきましょう。
まとめ
非常に便利なパッケージが開発されていて何よりです。
結構有名なプラグインなんかもこの方法でスコープを使い衝突を避けているようです。参考:WP MIGRATE DB PRO
衝突しない場合でもあらかじめスコープ付けておくと親切ですね。
余談
上記方法で私の場合は解決しませんでした。
テーマにスコープなしでパッケージが埋め込まれているのでどうしようもないし、変更したらアップデートできません。
そこで、google/apiclientを使用してanalyticsからデータを引っ張ってきていた部分を子テーマで別定義していたため、プラグインにgoogle/apiclientを入れて置き、autoloadの読み込みをプラグインにしてあげればいいのではないかと思いつきました。
(テーマ側でfunction_exisitsが使用されていなかったので、子テーマでカスタマイズしてあってラッキーでした。親テーマのままなら詰みでした。。。)
早速guzzlehttp/guzzle scotteh/php-dom-wrapperが入っているところにgoogle/apiclientをrequireします。
「ん、、、エラーが出てインストールできない。psrのバージョンが合わない。。。」
必至にエラー探って思いついた解決方法でも解決できず。。。
次に思いついたのそれぞれのバージョンが合うようにインストールする作戦。でも、これ面倒臭いですよね。composerの恩恵がゼロになる感じです。
なんとかならないかと思いながら検証中、ついにすべてインストールに成功しました。
苦労したかというとそうではなく、ただ逆に入れていくだけ。
google/apiclientを入れているところにguzzlehttp/guzzle scotteh/php-dom-wrapperをインストールするという方法です。
おかげ様ですべてエラーがなくなり、コンフリクトの解決もできました。