9

コードは言葉よりも上手に話します:

namespaces.php

<?php

namespace foo;

use foo\models;

class factory
{
    public static function create($name)
    {
        /*
         * Note 1: FQN works!
         * return call_user_func("\\foo\\models\\$name::getInstance");
         *
         * Note 2: direct instantiation of relative namespaces works!
         * return models\test::getInstance();
         */

        // Dynamic instantiation of relative namespaces fails: class 'models\test' not found
        return call_user_func("models\\$name::getInstance");
    }
}

namespace foo\models;

class test
{
    public static $instance;

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

        return self::$instance;
    }

    public function __construct()
    {
        var_dump($this);
    }
}

namespace_test.php

<?php

require_once 'namespaces.php';

foo\factory::create('test');

コメントしたように、内部で完全修飾名を使用するcall_user_func()と期待どおりに機能しますが、相対名前空間を使用すると、クラスが見つからなかったと表示されますが、直接インスタンス化は機能します。設計上、何かが足りないのでしょうか、それとも奇妙なのでしょうか。

4

2 に答える 2

11

コールバックでは完全修飾クラス名を使用する必要があります。

名前空間名を使用した例3を参照してくださいcall_user_func()

<?php

namespace Foobar;

class Foo {
    static public function test() {
        print "Hello world!\n";
    }
}

call_user_func(__NAMESPACE__ .'\Foo::test'); // As of PHP 5.3.0
call_user_func(array(__NAMESPACE__ .'\Foo', 'test')); // As of PHP 5.3.0

これはcall_user_func、グローバルスコープからの関数であり、グローバルスコープからのコールバックも実行しているためだと思います。いずれにせよ、最初の文を参照してください。

上記の注も参照してください。例2次のような名前空間要素に動的にアクセスする

完全修飾名(名前空間プレフィックス付きのクラス名)を使用する必要があります。

于 2013-02-04T07:50:34.580 に答える
2

PHPの現在のバージョンでは、現在の方法と同じです。文字列を使用してクラス名を参照する場合は、完全な名前空間で完全に修飾する必要があります。それは素晴らしいことではありませんが、それはそうです。

今後のPHPv5.5ではClassname::class、FQNクラス名を文字列に入れる代わりに使用できる新しい構文を提供することにより、これに対処する機能が含まれる予定です。

これに関する詳細については、関連するPHP RFCページを参照してください:https ://wiki.php.net/rfc/class_name_scalars

コードは次のようになります。

return call_user_func([models\$name::class,"getInstance"]);

それは正確ではないかもしれません。確認のためにテストする5.5のコピーがありません。しかし、いずれにせよ、新しい構文は、あなたのようなユースケースにとって物事をはるかに良くします。

于 2013-02-04T10:28:26.417 に答える