konekto Inc with PHP , MySQL コネクト株式会社 技術情報コンテンツ


Tips

2007年2月以前のポーティング事例

(以下の記事は2008年2月以降に実施のVer4からVer5へのマイグレーションサービスとは無関係の記事です。予めご承知おきください。)

PHP 5は、今までPHP 4で開発してきた資産を無駄にしないよう、互換性を重視して設計されている。
その互換性の高さを知る為にも、PHPマニュアル(www.php.net)を是非ご覧頂きたい。
このマニュアルはPHP全般について記述されており、互換性のない部分のみその旨が記されている。

PHP 5で失われた互換性の大半は、PHP 5になって新設された関数や例外処理などであり、既存の関数に関しては、ほぼ互換性を保たれている。
関数の動作については、互換性に関して過敏になる必要は無い。

しかし、実際にPHP 5へ移行した途端、エラーが発生してしまうケースは存在する。
どのようなケースがあるのだろうか。
弊社が関わった開発の中で、実際に確認したケースを挙げる。

コンパイラの仕様変更

スクリプト中にクォート(シングルクォート、ダブルクォート)で囲われていないキーワードがあった場合、PHP 3およびPHP 4ではこれをクォートで囲った文字列として認識していた。

だが、PHP 5では厳密に文法を検査するようになったため、この場合は定数として判断する。
互換性という点では問題ではあるが、そもそも文字列をクォートで囲わない点にも問題がある。
本来は、スクリプトをすべて修正すべきではあるが、次の方法で解決する事が可能である。

解決策

PHP 5では、Undefined Constant(未定義の定数を使用した)として判定されてしまうが、これを逆手に取って解決する。

該当する文字列をdefine()で定数として定義してしまうのである。
次のスクリプトは、PHP 3およびPHP 4では正常に動作するが、PHP 5では動作しない。

<?php
$a = ABC;
?>

ABCというキーワードは、未定義の定数として扱われる。
つまり、ABCというキーワードを定数として定義してしまえばよい。

<?php
define('ABC', 'ABC');
$a = ABC;
?>

上記のように、define()を追記する事で、このスクリプトは正常に動作するようになる。

但し、require()やinclude()で読み込まれるスクリプトで、同じキーワードが使われる場合、二重に定数を定義してしまう事になる。
全てのスクリプトからinclude_once()を行う為のスクリプトを用意し、そこに記述するのが望ましい。

関数名のエイリアス*1廃止

PHP 4では、mbstring系の関数の一部で、"mb_"から始まる関数に対し、"mb"から始まる関数名のエイリアスが用意されていたが、PHP 5ではこれが廃止された。
また、"i18n_"から始まる関数についても廃止されている。

これにより、廃止されたエイリアスを利用していたスクリプトでUndefined function(未定義の関数)エラーが発生するようになった。

解決策

未定義の関数と判断される事が原因なので、自分で関数を用意することで解決できる。
この時、関数の中では本来の関数を呼び出すようにすればよい。

サンプル

実際に、弊社でポーティング作業を担当した際の成果物の一部を紹介する。

このスクリプトを、i18n_convert()関数とi18n_ja_jp_hantozen()関数を、mbstring系関数に置き換えるための定義と、未定義のキーワードをdefine()で定数として定義している。

<?php
define
('EUC''EUC');
define('SJIS''SJIS');
define('K''K');
define('A''A');
define('n''n');
define('a''a');

function 
i18n_convert($str$to_encoding$from_encoding  null)
{
    if (
is_null($from_encoding)) {
        return 
mb_convert_encoding($str$to_encoding"SJIS");
    } else {
        return 
mb_convert_encoding($str$to_encoding$from_encoding);
    }
}


function 
i18n_ja_jp_hantozen($str$option$encoding null)
{
    if (
is_null($encoding)) {
        return 
mb_convert_kana($str$option"SJIS");
    } else {
        return 
mb_convert_kana($str$option$encoding);
    }
}

?>

このサンプルを見ていただければ、要点さえ抑えてしまえば比較的簡単にPHP 5に実現できる事がお分かり頂けるかと思う。


*1 別名定義の意。本来の名前とは別の名前を定義し、どちらでも使用できるようにする事。

添付ファイル: filei18n2mb.inc 3002件 [詳細]

最終更新のRSS