LoginSignup
4
1

More than 5 years have passed since last update.

【PHP】名前空間を使用したクラスのコンストラクタが実行されなかった話し

Last updated at Posted at 2018-03-07

古い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

今度はちゃんと動きました。
古いシステムは今の形に合わせてメンテナンスしないといけないですね。
ほっとくとクソコードが使いまわされてしまう可能性があるので気づいたら修正しましょう。

お疲れ様でした。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1