usar tipos metodos estaticos cuando php syntax

tipos - ¿Referencia al método estático en PHP?



static php (8)

En PHP, puedo usar una función normal como variable sin problema, pero no he descubierto cómo usar un método estático. ¿Me estoy perdiendo la sintaxis correcta, o esto no es posible?

(EDITAR: la primera respuesta sugerida no parece funcionar. He extendido mi ejemplo para mostrar los errores devueltos).

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

(Estoy usando PHP v5.2.6 - ¿la respuesta cambia dependiendo de la versión también?)



PHP maneja las devoluciones de llamadas como cadenas, no como punteros de función. La razón por la que su primera prueba funciona es porque el intérprete de PHP asume que foo1 es una cadena. Si tiene el error de nivel E_NOTICE habilitado, debería ver una prueba de eso.

"Uso de constante indefinida foo1 - se supone ''foo1''"

No puede llamar a los métodos estáticos de esta manera, desafortunadamente. El alcance (clase) es relevante, por lo que debe usar call_user_func en su lugar.

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


En php 5.2, puede usar una variable como el nombre del método en una llamada estática, pero para usar una variable como nombre de clase, tendrá que usar devoluciones de llamada como lo describe BaileyP.

Sin embargo, desde php 5.3, puede usar una variable como nombre de clase en una llamada estática. Asi que:

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


Esto parece funcionar para mí:

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


En PHP 5.3.0, también puedes hacer lo siguiente:

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


Además de lo que se dijo, también puedes usar las capacidades de reflexión de 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''); } }


Viniendo de un fondo de JavaScript y siendo mimado por él, acabo de codificar esto:

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

Para usarlo:

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

Es una función que devuelve una función que llama a la función que desea llamar. Suena elegante, pero como se puede ver en la práctica, es pan comido.

Funciona con espacios de nombres y la función devuelta debería funcionar igual que el método estático: los parámetros funcionan igual.


Puede usar el nombre completo del método estático, incluido el espacio de nombres.

<?php function foo($method) { return $method(''argument''); } foo(''YourClass::staticMethod''); foo(''Namespace/YourClass::staticMethod'');

El nombre array array(''YourClass'', ''staticMethod'') es igual a él. Pero creo que la cadena puede ser más clara para leer.