OpenPNE 2.12の PHP 7.2対応

大学時代のサークルの OB会メンバー間のコミュニケーション用として、2006年夏から OpenPNE の 2.x系をベースに日記などの画像表示系に少し手を入れたプライベートな SNSを運用しています。(PHPで動作するソフトウェアです)
OpenPNE的には 2010年夏頃に 2.x系はサポートが終わっていて、現在は 3.x系の開発が続いていますが、3.xへの移行時にちょうど仕事が忙しくて自分で手を入れた部分のマージをする時間がとれず、DBのマイグレーションツールも整備されていないので、その後も惰性で未だに 2.12を使っています。(^^;)

そうこうしているうちに 2018年12月には PHPも 5系が EOLを迎えてしまい、7への移行が必要になりましたが、OpenPNE 3.x系の PHP 7対応の進捗がはかばかしくないようだったので、少し悩んだ末に OpenPNE 2.12に対して自力で PHP 7.2対応をしました。(Smartyの新バージョンへの入れ替えを含む)

改修後半年を経過しましたが、特に問題もなく動いているようです。

今どき 2.x系を使っている方がいるとは思えないのでパッチとしての整理はしてありませんが、もし万が一ご要望があれば、(自分用のカスタマイズを除いた形での)パッチを公開することはできると思います。(2021/05現在、事情により整理の時間が取れません)

本来は 3.x系で PHP 7対応をして開発チームにフィードバックできれば格好良かったんでしょうね。(笑)

※ 2019/12/14追記

OpenPNE 2系をがっつりカスタマイズして納品・運用しているというソフトウェア会社の方からお問い合わせがあって、パッチのご要望ではなく、変更箇所の数とか作業時間、ハマりポイントなどについて質問されたのでお答えしました。
その内容は個別のカスタマイズの内容には無関係な一般的なものだったので、ほかの方にも何かのご参考になるかもしれないと思ったので、ここにまとめて追記します。

やったことと、およその所要時間

週末をはさんで5日ほどかけてやったというメモが残っていました。
その間で、

  • PHP 5系で動いている環境をコピーした検証用 VMを立てる (スナップショットを利用していつでも変更を元に戻せるように)
  • Smarty 2系の PHP 7対応版を PHP 5の環境にのせて動くことを確認した後に PHP 7で動かした時に出るエラーはすべて OpenPNEの修正で進められるはず、という仮説で進められそうかどうかのメドをつける
  • &new 問題をやっつける (find と (e)grepの力業 ^^;)
  • PHP 7系にして、ログを流し見つつ動かして、エラーになっている関数(ereg[i]()など)が出てきたら全体を grepして地道につぶす
  • PEAR::DBの mysql driverが廃止されているので mysqli driverに変更 (config変更)
  • ひと通りの動作確認ができたら、本家の公開版からのパッチを作成
  • 運用中の環境への適用(バックアップ、PHPのバージョンアップ、パッチ当て)

という感じで進めたので、実際の作業時間はおそらく 20~25時間程度だったかと思います。

変更箇所

すでに若干のカスタマイズ(具体的には画像表示用に使われている lightboxをズーム操作のできる別の派生物に差し替え)をしてあったものに対して PHP 7対応をした後のソースコードと、同じバージョンの配布物のソースコードとの Unified diffファイルについて調べてみたところ、ファイルの行数は 83040行でした。
一見、非常に大きいのですが Smarty 2系のバージョンアップによる差分がほとんどを占めますので、自力で対応した個所はこれより 3桁くらい少ないです。(笑)

一番変更が多かったのは
    foo = & new bar()

    foo = new bar()
に変更したところで、84か所。

次が ereg*() を preg_*()に変更したところで 7か所。

他には、

  • sizeof() の前に is_array()のチェックを付加 (数ヶ所)
  • 条件式によっては isset()のチェックを付加 (数ヶ所)
  • OpenPNE_Smarty()での Smartyのコンストラクタ呼び出し方法を $this->Smarty() から $this->__construct(); に変更
  • 文字列リテラルを「'」で括っていない箇所の修正 (やや多め)
  • classを継承してメソッドをオーバーライドした際に、引数などの定義が親classと一致していない 箇所の修正 (warningなので無視してもいいけど気になるので)

をしたくらいです。

コードの他に設定としては PEAR::DBの mysql driverを mysqli driverに変更するよう configファイルを書き換えました。

ハマったポイント

上記の修正で閲覧・検索に関してはエラーで落ちることもなく動き始めましたが、日記など何かを追加するとエラーなく追加できるのに追加したものが見つからない、という問題が発覚しました。

DBの追加処理系に問題がありそうという事はわかりますが、その原因が、

  • 一部の関数で、
    • configに書かれている PEAR::DBの driverによって mysqlとそれ以外で使用する SQLを分けている

という動作をしていて、mysqliの場合には「mysql以外」(具体的には postgresql)として動作していたため

ということに気づくまでに少し手間取りました。(具体的には追加されたレコードのシーケンスを採番する時の SQLの違い)
この対応のための変更箇所は 3か所でした。

雑感

規模の割には修正箇所は少なかったように思いました。
DBレイヤの切り分け方なども素直で推測しやすかったです。
PostgreSQL対応が中途半端(正式サポートされていないので文句は言えません)なのが、個人的に MySQLより PostgreSQLの方が好きな私としては残念です。
将来、自由な時間が取れるようになった時に OpenPNE 3のコミュニティーが元気だったら、開発にも関わってみたいと思いました。

以上です。

※ 2021/05/10追記

ある方からパッチ提供についてのお問合せがあったので、久しぶりに OpenPNEのサイトを見てみたら、2020/03/12リリースの OpenPNE 3.10.0 からは PHP7対応されているようです。

OpenPNE 2系は開発終了からずいぶん時間が経っていて、仮にセキュリティホールが見つかっても fixが出ることは期待できないので、3系への移行を考えるべき時期だと思われます。(自戒を込めて)