破棄されたブログ

このブログは破棄されました。

PHP の関数内関数

PHP で関数内関数とかできること知らんかった。

<?php
var_dump(function_exists('fuga')); // false

function hoge() {
    var_dump(function_exists('fuga')); // false
    function fuga() {}
    var_dump(function_exists('fuga')); // true
}

var_dump(function_exists('fuga')); // false
hoge();
var_dump(function_exists('fuga')); // true
?>
<?php
class Hoge {
    public function fuga() {
        function foo() {}
    }
}
var_dump(function_exists('foo')); // fasle
(new Hoge())->fuga();
var_dump(function_exists('foo')); // true
?>

関数の中では、他の関数や クラス 定義 を含む PHP のあらゆる有効なコードを使用することができます。

PHP: ユーザー定義関数 - Manual

なんでもアリだったのね。 PHP4 でもうごいた。

クラスの中には、 定数 や 変数 ("プロパティ" といいます) そして関数 ("メソッド" といいます) を含めることができます。

PHP: クラスの基礎 - Manual

とか書いてあって、マニュアルにメソッドのリファレンスがないんで、メソッドも関数同様にクラス定義とかできるのかと思ったら、それはできないみたい。
(でも、include/require したコードのクラス定義はエラー出なかったような。。。)

<?php
class Hoge {
    public function fuga() {
        class Foo{} // Fatal error: Class declarations may not be nested on line 4
    }
}
?>

関数内の変数のスコープはローカルスコープだから、関数内関数もローカルスコープに…ならない。。。

PHP では、関数やクラスはすべてグローバルスコープにあります - 関数の内部で定義したものであっても関数の外部からコールできますし、 その逆も可能です。

PHP: ユーザー定義関数 - Manual

意外だったのは、グローバルスコープで宣言された関数は、関数宣言前に呼び出しが可能なのにもかかわらず、関数内関数は関数内で宣言されるまで呼び出せない。
JavaScript の場合だと、関数内で関数を定義するとスコープは関数内になるし、名前付き関数は、関数宣言を含む実行コンテキストに入った時に初期化される(function foisting, 関数のホイスト)。JS ほうが好み。

マニュアル読み返すと意外な仕様が埋まってるんで、実にアレ。
パーフェクト PHP ください

パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)

広告を非表示にする