2012-03-02 10 views
6

tengo una clase:cómo usar la constante de la clase como una definición de argumento en la función php?

class FetchMode 
{ 
const FetchAll = 0; 
const FetchOne = 1; 
const FetchRow = 2;} 

y una función:

function getRecordSet(FetchMode $FetchMode){ some switch cases } 

me gustaría usar $ fetchMode como criterios de caso interruptor pero recibiendo un error: error grave capturable: argumento pasado a getRecordSet() debe ser una instancia de FetchMode, número entero dado

así es como llamo una función:

getRecordSet(FetchMode::FetchOne); 

Me gustaría ofrecer una lista de posibles opciones para llamar a una función. ¿Es posible en php?

+0

FetchMode :: FetchOne resuelve en 1, por lo que realmente pasa 1 a la función, no un objeto del tipo FetchMode. No sé lo que quiere lograr, pero tenga en cuenta que debe pasar un objeto de tipo FetchMode a su función, por lo que necesita algún tipo de '' $ fm = new FetchMode(); '' – Sgoettschkes

Respuesta

8

Tienes hinted PHP esperar una instancia de FetchMode (como se dice en el mensaje de error), pero FetchMode::FETCH* pasa la constante valor. Tendría que usar algún tipo de instancia de Enum (que no tenemos de forma nativa en PHP. (Bueno, hay SplEnum, pero ¿quién usa eso?)) O cambie la firma del método para excluir el typehint.

Sin embargo, en lugar de un Switch/Case puede solve this more easily via Polymorphism y Strategy pattern, p. Ej. en vez de hacer algo así como

public function getRecordSet($mode) 
{ 
    switch ($mode) { 
     case FetchMode::ALL: 
      // code to do a fetchAll 
      break; 
     case FetchMode::ONE: 
      // code to do a fetchOne 
      break; 
     default: 
    } 
} 

lo que aumentará la Cylcomatic Complexity de sus clases y fuerzas de cambio en esa clase y FetchMode cada vez que es necesario agregar FetchModes adicionales, puede hacerlo:

public function getRecordSet(FetchMode $fetchModeStrategy) 
{ 
    return $fetchModeStrategy->fetch(); 
} 

y después de haber una clase concreta interface a protect the variation

interface FetchMode 
{ 
    public function fetch(); 
} 

y añadir FetchMode es para cada apoyaron fetchMode

class FetchOne implements FetchMode 
{ 
    public function fetch() 
    { 
     // code to fetchOne 
    } 
} 
class FetchAll … 
class FetchRow … 

De esta manera, usted nunca tiene que tocar la clase con que getRecordSet método de nuevo, ya que funcionará para cualquier clase de implementación que FetchMode inteface.Por lo tanto, cada vez que tenga nuevos FetchModes, simplemente agregue una nueva clase, que es mucho más fácil de mantener en el largo plazo.

0

No sé qué quiere decir con

would like to offer a list of possible choices in calling a function. Is it possible in php?

pero por la parte de error: Imagine que tiene un var, por ejemplo, $foo. Cuando lo haces echo $foo no obtienes el nombre de la var sino su valor. Esto se debe a que una var tiene un nombre y apunta a un valor. Cada acceso a la var básicamente devuelve el valor al que apunta. Es lo mismo con las constantes; Pones el nombre constante allí, pero básicamente estás apuntando a tu valor almacenado. Lo que significa getRecordSet(FetchMode::FetchOne); y getRecordSet(1); es lo mismo.

Por lo tanto, getRecordSet(FetchMode $FetchMode) aumenta must be an instance of FetchMode porque FetchMode::FetchOne apunta a un número entero.

Para solucionar esto, necesita usar getRecordSet(int $FetchMode).

+0

I Don ' Quiero obligar a otros desarrolladores a saber qué opción tiene qué valor. Es por eso que estoy tratando de usar functionname (FetchMode :: FetchOne) en lugar de functionname (1) – dllhell

+1

que no tienen que saber. Todavía puedes usar 'FetchMode :: FetchOne' pero tu declaración de función todavía toma' 'int' y no' FetchMode' como argumento (porque tu argumento apunta a 'int' y no a una instancia de' FetchMode') a menos que estás usando un patrón de estrategia como Gordon explica en su respuesta. – pduersteler

Cuestiones relacionadas