22

PHPでは、通常の関数を変数として問題なく使用できますが、静的メソッドの使用方法がわかりません。正しい構文が欠落しているだけですか、それとも不可能ですか?

(編集:最初に提案された答えは機能しないようです。返されたエラーを表示するために例を拡張しました。)

function foo1($a,$b) { return $a/$b; }

class Bar
{
    static function foo2($a,$b) { return $a/$b; }

    public function UseReferences()
    {
        // WORKS FINE:
        $fn = foo1;
        print $fn(1,1);

        // WORKS FINE:
        print self::foo2(2,1);
        print Bar::foo2(3,1);

        // DOES NOT WORK ... error: Undefined class constant 'foo2'
        //$fn = self::foo2;
        //print $fn(4,1);

        // DOES NOT WORK ... error: Call to undefined function self::foo2()
        //$fn = 'self::foo2';
        //print $fn(5,1);

        // DOES NOT WORK ... error: Call to undefined function Bar::foo2()        
        //$fn = 'Bar::foo2';
        //print $fn(5,1);

     }
}

$x = new Bar();
$x->UseReferences();

(私はPHP v5.2.6を使用しています-バージョンによっても答えは変わりますか?)

4

8 に答える 8

30

PHP はコールバックを関数ポインタではなく文字列として扱います。最初のテストが機能する理由は、PHP インタープリターがfoo1を文字列と見なすためです。E_NOTICE レベルのエラーが有効になっている場合は、その証拠が表示されるはずです。

「未定義の定数 foo1 の使用 - 'foo1' と見なされます」

残念ながら、この方法で静的メソッドを呼び出すことはできません。スコープ (クラス) は関連しているため、代わりに call_user_func を使用する必要があります。

<?php

function foo1($a,$b) { return $a/$b; }

class Bar
{
    public static function foo2($a,$b) { return $a/$b; }

    public function UseReferences()
    {
        $fn = 'foo1';
        echo $fn(6,3);

        $fn = array( 'self', 'foo2' );
        print call_user_func( $fn, 6, 2 );
     }
}

$b = new Bar;
$b->UseReferences();
于 2008-10-10T16:22:25.130 に答える
10

php 5.2では、静的呼び出しでメソッド名として変数を使用できますが、クラス名として変数を使用するには、BaileyPで説明されているようにコールバックを使用する必要があります。

ただし、php 5.3以降では、静的呼び出しでクラス名として変数を使用できます。それで:

class Bar
{
    public static function foo2($a,$b) { return $a/$b; }

    public function UseReferences()
    {
        $method = 'foo2';
        print Bar::$method(6,2); // works in php 5.2.6

        $class = 'Bar';
        print $class::$method(6,2); // works in php 5.3
     }
}

$b = new Bar;
$b->UseReferences();
?>
于 2008-10-10T18:32:55.930 に答える
6

名前空間を含む静的メソッドの完全な名前を使用できます。

<?php
    function foo($method)
    {
        return $method('argument');
    }

    foo('YourClass::staticMethod');
    foo('Namespace\YourClass::staticMethod');

名前配列array('YourClass', 'staticMethod')はそれと同じです。しかし、文字列は読みやすくなっていると思います。

于 2012-06-20T06:43:55.127 に答える
1

PHP 5.3.0 では、次のこともできます。

<?php

class Foo {
    static function Bar($a, $b) {
        if ($a == $b)
            return 0;

        return ($a < $b) ? -1 : 1;
    }
    function RBar($a, $b) {
        if ($a == $b)
            return 0;

        return ($a < $b) ? 1 : -1;
    }
}

$vals = array(3,2,6,4,1);
$cmpFunc = array('Foo', 'Bar');
usort($vals, $cmpFunc);

// This would also work:
$fooInstance = new Foo();
$cmpFunc = array('fooInstance', 'RBar');
// Or
// $cmpFunc = array('fooInstance', 'Bar');
usort($vals, $cmpFunc);

?>
于 2010-08-20T05:05:38.940 に答える
1

JavaScriptのバックグラウンドから来て、それに甘やかされて、私はこれをコーディングしました:

function staticFunctionReference($name)
{
    return function() use ($name)
    {
        $className = strstr($name, '::', true);
        if (class_exists(__NAMESPACE__."\\$className")) $name = __NAMESPACE__."\\$name";
        return call_user_func_array($name, func_get_args());
    };
}

使用するには:

$foo = staticFunctionReference('Foo::bar');
$foo('some', 'parameters');

呼び出したい関数を呼び出す関数を返す関数です。派手に聞こえますが、実際に見てわかるように、それは簡単なことです。

名前空間で動作し、返される関数は静的メソッドと同じように動作する必要があります-パラメーターは同じように動作します。

于 2013-12-18T04:02:43.050 に答える
0

言われたことに加えて、PHPのリフレクション機能を使用することもできます。

class Bar {

    public static function foo($foo, $bar) {
        return $foo . ' ' . $bar;
    }


    public function useReferences () {
        $method = new ReflectionMethod($this, 'foo');
        // Note NULL as the first argument for a static call
        $result = $method->invoke(NULL, '123', 'xyz');
    }

}
于 2013-01-08T04:01:48.870 に答える
0

これは私にとってはうまくいくようです:

<?php

class Foo{
    static function Calc($x,$y){
        return $x + $y;
    }

    public function Test(){
        $z = self::Calc(3,4);

        echo("z = ".$z);
    }
}

$foo = new Foo();
$foo->Test();

?>
于 2008-10-11T09:25:03.553 に答える
-3

「静的で宣言されたメンバーまたはメソッドは、オブジェクトのインスタンスである変数でアクセスできず、拡張クラスで再定義できません」

( http://theserverpages.com/php/manual/en/language.oop5.static.php )

于 2008-10-10T16:51:23.607 に答える