2010-01-21 12 views
51

Por favor alguien con experiencia en PHP puede ayudar con lo siguiente. En algún lugar de mi código, tengo una llamada a un método estático público dentro de una clase no instanciado:Llamada a un método estático dinámico en PHP?

$result = myClassName::myFunctionName(); 

Sin embargo, me gustaría tener muchas de estas clases y determinar el nombre de la clase correcta sobre la marcha de acuerdo con el idioma del usuario En otras palabras, no tengo:

$language = 'EN'; 

... y necesito hacer algo como:

$result = myClassName_EN::myFunctionName(); 

Sé que podría pasar el lenguaje como un parámetro a la función y tratar con él en el interior solo una clase común, pero por diversas razones, preferiría una solución diferente.

¿Tiene esto algún sentido, alguien? Gracias.

+1

Para responder a sus últimas 3 líneas, no tiene mucho sentido, a menos que tenga una razón específica por la que no puede implementar el modo "pasar el idioma como parámetro" –

+3

Sí, tengo una razón específica ... Se relaciona con la administración de traducciones de una manera más sensata para varias cosas que suceden dentro de esas clases. Es complicado :) – Tom

Respuesta

96

Utilice la función call_user_func:

http://php.net/manual/en/function.call-user-func.php

Ejemplo:

call_user_func('myClassName_' . $language . '::myFunctionName'); 
+24

Combinado con 'is_callable' y' method_exists' esta sería también mi recomendación. Para pasar los parámetros mira 'call_user_func_array' http://php.net/is_callable http://php.net/method_exists http://php.net/call_user_func_array –

+1

+1, concuerdo nikc :-) –

+0

Este tipo de trabajos y parece la solución más limpia. Gracias – Tom

3

aunque yo creo que la forma de tratar es una muy mala idea, creo que puede tener una solución

$className = 'myClassName_'.$language; 
$result = $className::myFunctionName(); 

creo que esto es lo que quiere

+0

haha ​​snap! me ganaste por 45 segundos –

+0

¿Podrías decirme por qué es tan mala idea? – Tom

+0

puede usar el lenguaje como parámetro, en su lugar elige definir una nueva clase para él. Digamos que quieres apoyar 200 idiomas diferentes, te sentarás y escribirás 200 clases diferentes. También hará que su código sea extremadamente difícil de leer y entender. – marvin

12

I que que podría hacer:

$classname = 'myClassName_' . $language; 
$result = $classname::myFunctionName(); 

Esto se llama Variable Functions

+4

Es una lástima que esto solo funcione en> = 5.3.0 :( –

+0

Para mí , esta es la mejor solución. Y según mi banco, este es el más rápido también: 100,000 iteraciones tomaron 0.28s con llamada directa, 0.32 con esta solución, y 0.47 con call_user_func – fred727

1

Por lo que yo podía entender su pregunta, usted necesita para obtener el nombre de la clase que se puede hacer utilizando get_class función . Por otro lado, el Reflection class puede ayudarlo aquí, que es excelente cuando se trata de métodos, argumentos, etc. en forma de OOP.

13

Me gustaría encapsular la creación de la clase que necesita en una fábrica.

De esta manera tendrá un único punto de entrada cuando necesite cambiar su nombre base o las reglas para asignar el idioma a la clase correcta.

class YourClassFactory { 

     private $_language; 
     private $_basename = 'yourclass'; 

     public YourClassFactory($language) { 
      $this->_language = $language; 
     } 

     public function getYourClass() { 
      return $this->_basename . '_' . $this->_language; 
     }  
    } 

y luego, cuando se tiene que usarlo:

$yourClass = $yourClassFactoryInstance->getYourClass(); 
$yourClass::myFunctionName(); 
0

soluciones como:

$yourClass::myFunctionName(); 

no va a funcionar. PHP producirá un error de análisis.

Desafortunadamente, la única forma es usar muy lentocall_user_func().

+3

Solo en <5.3.0 esto no está permitido. 5.3.0 está permitido. –

+0

http://uk3.php.net/manual/en/language.variables.variable.php y http://uk3.php.net/manual/en/functions.variable-functions. php :) – tftd

6

Como dijo Temuri, se produce error de análisis, al intentar '$ className :: functionName':

Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM ...

En mi caso (método estático con 2 argumentos), mejores soluciones es utilizar call_user_func_array con 2 matrices (según lo sugerido por nikc.org):

$result = call_user_func_array(array($className, $methodName), array($ard1, $arg2)); 

BR

-1

sé que es un hilo viejo, pero a partir de PHP 5.3.0 usted debe utilizar forward_static_call

$result = forward_static_call(array('myClassName_EN', 'myFunctionName')); 

Uso de la variable de idioma $, puede ser que parezca:

$result = forward_static_call(array('myClassName_' . $language, 'myFunctionName')); 
+0

No funcionará. Llama a una función definida por el usuario o método dado por el parámetro de la función, con los siguientes argumentos. Esta función debe invocarse dentro de un contexto de método, no puede usarse fuera de una clase ... como se menciona en http://php.net/manual/en/function.forward-static-call.php –

1

Usted puede hacer a continuación:

<?php 

class B { 

    public static $t = 5; 

    public static function t($h) { 
     return "Works!" . $h; 
    } 
} 

$g = 't'; 
$class = 'B'; 

echo $class::$g('yes'); //Works! Yes 

Y lo hará funciona bien, probado en PHP 5.2> =

Cuestiones relacionadas