2011-06-27 11 views
7

Me pregunto cuál crees que es la mejor práctica aquí. ¿Te cuesta mucho comprobar los parámetros en PHP? Es decir, ¿ha visto realmente menos errores en proyectos en los que ha implementado la comprobación de tipos de parámetros frente a los que no? Estoy pensando en cosas como esta:php type checking for method parameters - ¿Vale la pena?

public function __construct($screenName, $createdAt) { 
     if (!is_string($screenName) || !is_string($createdAt) { 
      return FALSE; 
     } 
} 
+5

Si desea la verificación de tipo, use un lenguaje estático. – delnan

+0

Solo he usado el tipo de comprobación con matrices. Entonces dejé de volver a usar variables con diferentes tipos. – jous

+1

He visto menos errores en proyectos bien planificados y escritos. ¿Esto cuenta? ;) Por cierto: '$ createdAt' también puede ser una marca de tiempo (' int'), o un objeto ('DateTime'). – KingCrunch

Respuesta

5

Normalmente, dentro de una aplicación PHP que hace uso de la variable skalar "tipos" está vinculada a la entrada de cadena realmente (solicitud HTTP). PHP hizo esto más fácil para convertir la entrada de cadena a números para que pueda usarla para el cálculo y tal.

Sin embargo, verificar los valores escalares para is_string como se propone en su ejemplo no tiene mucho sentido. Porque casi cualquier tipo de variable en la familia escalar es una cadena o al menos se puede usar como una cadena. En cuanto a su ejemplo de clase, la pregunta sería: ¿tiene sentido verificar el tipo de variable o no?

Para el código que ha propuesto, no tiene ningún sentido porque sale del constructor con un return false;. Esto terminará el constructor para ejecutar y devolver un objeto no inicializado correctamente.

En su lugar, debe lanzar una excepción, p. un InvalidArgumentException si un argumento de constructores no proporciona el tipo de valor esperado/necesario.

Dejando esto de lado y dando por hecho que su constructor de objetos necesita diferenciar entre una cadena y un entero o bool o cualquier otro tipo escalar, entonces debe hacer las comprobaciones.

Si no confía en los tipos escalares exactos, puede convertir a cadena en su lugar.

Solo asegúrese de que los datos ocultos dentro del objeto siempre son perfectamente correctos y no es posible que los datos incorrectos puedan pasar a miembros privados.

+0

Buena respuesta, gracias. –

+0

De nada. – hakre

6

Depende. Generalmente usaré el type-hinting que está integrado en PHP para objetos de nivel superior ((stdClass $ obj, array $ arr, MyClass $ mine)), pero cuando se trata de valores de nivel más bajos, especialmente números y cadenas, se convierte en un poco menos beneficioso

Por ejemplo, si tiene la cadena '12345', eso se vuelve un poco difícil de diferenciar entre eso y el número 12345.

Para todo lo demás, la fundición accidental de matriz a una cadena será obvia. Las instancias de clase que se envían a cadenas, si no tienen un __toString, harán que PHP grite. Entonces, su único problema real son las clases que tienen un método __toString y, bueno, eso realmente limita el número de veces que puede aparecer. Realmente me pregunto si vale la pena ese nivel de sobrecarga.

+1

Buena respuesta, gracias. –

0

Mejor documentación es más importante cuando usted es el único que interactúa con los métodos. Los comentarios de definición de métodos estándar le proporcionan métodos bien documentados que pueden compilarse fácilmente en una API que luego se usa en muchos IDE.

Sin embargo, cuando expone sus bibliotecas o sus entradas a otras personas, es bueno hacer una comprobación de tipos y lanzar errores si su código no funciona con su entrada. La verificación de tipo a la entrada del usuario lo protege de los errores y los intentos de pirateo, y como una biblioteca que les permite a otros desarrolladores saber que la entrada que proporcionaron no es lo que están esperando, a veces es agradable.

2

Verificar los argumentos de la función es una muy buena práctica.Sospecho que la gente a menudo no hace eso porque sus funciones crecen y el código se vuelve más feo y menos legible. Ahora con PHP 7 puede escribir tipos escalares de sugerencias, pero todavía no hay solución para casos en los que desee que su parámetro sea de uno de dos tipos: array o instancia de \ Traversable (que ambos pueden recorrerse con foreach).

En este caso, recomiendo echar un vistazo a args module desde NSPL. El __constructor de su ejemplo tendrá el siguiente aspecto:

public function __construct($screenName, $createdAt) 
{ 
    expectsAll(string, [$screenName, $createdAt]); 
} 

// or require a non-empty array, string or instance of \ArrayAccess 
function first($sequence) 
{ 
    expects([nonEmpty, arrayAccess, string], $sequence); 
    return $sequence[0]; 
} 

Más ejemplos here.