LoginSignup
2
0

More than 5 years have passed since last update.

シングルトンのクラスのメンバ関数内で内部関数を定義する際の注意(追記あり)

Last updated at Posted at 2016-12-05

※ 下の方に追記があります

シングルトンのクラスのメンバ関数の中に内部関数を定義する場合、
既に定義されてるかチェックしないと、再宣言でエラーになるので、
内部関数の宣言前に function_exists() でチェックしましょう。

class Singleton
{
    private static $instance;

    private function __construct()
    {
    }

    public static function getInstance()
    {
        if (!self::$instance) self::$instance = new Singleton;
        return self::$instance;
    }

    public function memberFunction()
    {
        // 内部関数を定義する場合は関数が定義されてないかチェック
        if (!function_exists('innerFunction')) {
            function innerFunction()
            {
                echo 'Hello';
            }
        }

        innerFunction();
    }

    final function __clone()
    {
        throw new \Exception('Clone is not allowed against' . get_class($this)); 
    }
}

class Test extends Singleton
{
}

$test = Test::getInstance();
$test->memberFunction();
$test->memberFunction();   // チェックしていないと、"PHP Fatal error:  Cannot redeclare innerFunction()"

というか内部関数はメンバ関数として宣言したほうが安心ですね。

追記

コメント欄にて情報をいただいたのですが、
内部関数はクロージャとして定義すると関数定義がスコープの中に入るので、再定義にならずに済みそうです。

↓シンプルになり良いですね。

class Singleton
{
    private static $instance;

    private function __construct()
    {
    }

    public static function getInstance()
    {
        if (!self::$instance) self::$instance = new Singleton;
        return self::$instance;
    }

    public function memberFunction()
    {
        // 内部関数を定義する場合は関数が定義されてないかチェック
        $innerFunction = function()
        {
            echo 'Hello';
        };

        $innerFunction();
    }

    final function __clone()
    {
        throw new \Exception('Clone is not allowed against' . get_class($this)); 
    }
}

class Test extends Singleton
{
}

$test = Test::getInstance();
$test->memberFunction();
$test->memberFunction();
2
0
2

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
2
0