PEARとの共存

この機能拡張では、PEARのI18n_UnicodeNormalizerパッケージを使用しています。書いている当人がPHPやPEARに詳しいわけではないのですが、ContaoでPEARを使用する際に問題となる部分がありました。

すべてのPEARのパッケージで問題となるわけではありませんが、かなり厄介な問題でもあります。

PEARとSystemクラス

PEARは、PHPだけで実装されたパッケージ群です。PEARの基本部分であるPEARパッケージ(これを書いている時点ではPEAR-1.9.1)をインストールすると、PHPのライブラリを探す先とするディレクトリに、

    System.php

というファイルがインストールされ、中には"System"というクラスがそのまま定義されています。この中には動作プラットフォームに依存しない、ファイルやディレクトリを操作する関数が定義されています。

これらはPEARのパッケージを管理するコマンドで使用する目的のようで、それ以外の個々のPEARのパッケージが動作するために必須とは言えず、実際に使用していないPEARのパッケージの方が多いようです。しかし、中には動作プラットフォームに依存しないファイル操作やディレクトリの操作に使用しようとしているものもポツポツとあるようです。

一方、ContaoにもSystemというクラスが定義されていて、Contaoのクラスライブラリの中でも重要なものの1つです。このため、PEARのパッケージでPEARのSystem.phpを使用しているものがあると、Systemのクラスを二重定義しようとして魔法のように処理が途中で終わります。

I18n_UnicodeNormalizerの場合

I18n_UnicodeNormalizerの場合はUnicodeの文字変換のために実行時に使用するデータ、実際はPHPのコード群を含めたディレクトリdataに置いています。このディレクトリはソース中ではI18Nのディレクトリの直下にあり、そこにある場合は開発中の状態と判断して、そのまま使用します。

I18n_UnicodeNormalizerのPEARパッケージをインストールすると、dataはI18Nのディレクトリの直下には置かれず、その一を探すためにSystem.phpを使用してしまいます。

結果的に、Contaoが動作しなくなります。

解決策

I18N_UnicodeNormalizerの場合、幸いなことにdataのディレクトリがソースと同じ位置にあれば、そのまま使用します。そこで、この機能拡張ではI18N_UnicodeNormalizerのソースをそのまま含めてしまうことで問題を回避することにしました。

何かもっと良い解決方法がありそうな気もするのですが、根本的にPEAR側の作りが悪いようにも思えます。理解した範囲ではSystem.phpはPEARのパッケージを管理するコマンドで使用する目的のように思えますし、プラットフォームに依存しないファイル操作としては用意されている内容が充実しているとも思えません。

ただ、私自身はPEARの実装方針を理解しているわけではありませんので、本当のところをご存知の方には教えていただきたいところです。