※ 下の方に追記があります
シングルトンのクラスのメンバ関数の中に内部関数を定義する場合、
既に定義されてるかチェックしないと、再宣言でエラーになるので、
内部関数の宣言前に 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();