古いPHPプラグラムを改修していると意外とあるかもしれない事例です。
同一クラス名を定義した場合
同じクラス名を定義している2ファイルを読み込み実行してみます。
hoge.php
<?php
class Hoge {
function Hoge() {
echo 'filename is hoge.php' . PHP_EOL;
}
}
hogehoge.php
<?php
class Hoge {
function Hoge() {
echo 'filename is hogehoge.php' . PHP_EOL;
}
}
test.php
<?php
require_once('hoge.php');
require_once('hogehoge.php');
$hoge = new Hoge();
$ php test.php
Fatal error: Cannot declare class Hoge, because the name is already in use in hogehoge.php on line 3
当然ですが既に使われているクラス名で定義しようとしエラーになります。
名前空間を使用する
この問題を解決するために名前空間を定義します。
名前空間について:http://php.net/manual/ja/language.namespaces.rationale.php
※ファイルの例が身近な例えでわかりやすいです。
hogehoge.phpに名前空間を定義します。
hogehoge.php
<?php
namespace hogehoge; # 追加
class Hoge {
function Hoge() {
echo 'filename is hogehoge.php' . PHP_EOL;
}
}
hogehoge.phpの修正に合わせ、呼び出し元も修正します。
test.php
<?php
require_once('hoge.php');
require_once('hogehoge.php');
$hoge = new Hoge();
$hoge2 = new hogehoge\Hoge(); # 名前空間hogehoge
実行してみましょう。
$ php test.php
filename is hoge.php
今度はエラーならず動作しましたね。と思いきやhogehoge.phpのコンストラクタが実行されません。
コンストラクタの仕様
公式にしっかり書いてありました。
http://php.net/manual/ja/language.oop5.decon.php
PHP 5.3.3以降、名前空間つきのクラス名の最後の部分と同じ名前のメソッドは、コンストラクタとみなされなくなりました。
古い形式のコンストラクタを修正しましょう。
hogehoge.php
<?php
namespace hogehoge;
class Hoge {
function __construct() { # 修正
echo 'filename is hogehoge.php' . PHP_EOL;
}
}
$ php test.php
filename is hoge.php
filename is hogehoge.php
今度はちゃんと動きました。
古いシステムは今の形に合わせてメンテナンスしないといけないですね。
ほっとくとクソコードが使いまわされてしまう可能性があるので気づいたら修正しましょう。
お疲れ様でした。