【要注意】WordPressでのcomposerパッケージコンフリクト

【要注意】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-plugin
composer bin php-scoper config minimum-stability dev
composer bin php-scoper config prefer-stable true 
composer 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をインストールするという方法です。

おかげ様ですべてエラーがなくなり、コンフリクトの解決もできました。