PHP statik yönteme başvurmak?

8 Cevap php

PHP, ben sorunsuz bir değişken olarak bir normal işlevini kullanmak mümkün duyuyorum, ama ben statik yöntemi kullanmak nasıl çözemedim. Ben sadece doğru sözdizimi eksik, ya da bu mümkün değildir muyum?

(EDIT: İlk önerilen cevap çalışmak için görünmüyor ben hataları döndü göstermek için benim örnek uzattık.).

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 kullanıyorum - cevap değişiklik çok sürümüne bağlı nedir?)

8 Cevap

PHP dizeleri değil, işlev işaretçileri gibi geri çağrıları yönetir. PHP yorumlayıcı foo1 bir dize olarak varsayar çünkü ilk test çalışır nedenidir. Eğer etkin E_NOTICE seviyesinde bir hata varsa, bu kanıtı görmelisiniz.

"Tanımsız sabit foo1 Kullanımı - 'foo1' varsayılır"

Ne yazık ki, statik yöntemler bu şekilde diyemem. Yerine call_user_func kullanmanız gerekir böylece kapsam (sınıf) geçerlidir.

<?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();

Php 5.2, statik bir çağrı yöntemi adı gibi bir değişken de kullanabilirsiniz, ancak sınıf adı olarak bir değişken kullanmak için, BaileyP tarafından açıklandığı gibi geri aramaları kullanmak gerekecek.

However, from php 5.3, you can use a variable as the class name in a static call. So:

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();
?>

Hemen ad dahil tam adı dizesi kullanabilirsiniz.

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

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

Ad dizisi array('YourClass', 'staticMethod') ona eşittir, ama ben dize okunacak daha açık olduğunu düşünüyorum.

Bu benim için iş gibi görünüyor:

<?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();

?>

PHP 5.3.0 'da, siz de aşağıdaki yapabilirdi:

<?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);

?>

Söylenenleri ek olarak PHP'nin yansıması yeteneklerini kullanabilirsiniz:

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');
    }

}

Bir javascript arka plan gelen ve onun tarafından şımarık, ben sadece bu kodlu:

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());
    };
}

Kullanmak için:

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

Bu aramak istedim işlevini çağıran bir fonksiyon döndüren bir fonksiyon. Kulağa hoş geliyor ama pratikte gördüğünüz gibi kek parçası.

Ad alanları ve dönen fonksiyonu ile eserler sadece statik yöntemi gibi çalışması gerekir - parametreleri aynı çalışır.

"Statik ile bildirilen bir üye veya yöntem nesnenin bir örneği olan ve uzanan bir sınıfta yeniden tanımlanamaz bir değişken ile erişilemiyor"

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