2011-02-19 18 views
6

me encuentro haciendo esto mucho:PHP: las mejores prácticas para la Insuficiencia silencioso

$something = @$_GET['else']; 
if ($something) { 
    // ... 
} else { 
    // ... 
} 

Al igual que, casi siempre trato con matrices. Estoy acostumbrado a JavaScript y la capacidad de simplemente comprobar si hay un valor falso. ¿Pero es esto apropiado en PHP? ¿Estoy tratando de forzar que PHP sea algo que ya entiendo, en lugar de aprenderlo como un lenguaje propio?

EDITAR

I udnerstand que solo puedo usar isset (también bajo * * soportarlo), pero se siente torpe para mí, y que conduce a situaciones aún clunkier donde yo estoy tratando de eco el valor:

// what I want to do 
echo '<input type="text" name="whatever" value="', @$values['whatever'], '" />'; 

// what I fear I must do 
echo '<input type="text" name="whatever" value="'; 
if (isset($values['whatever'])) { 
    echo $values['whatever']; 
} 
echo '" />'; 

Dejando de lado el problema de saneamiento, prefiero la primera versión. Pero tengo una sospecha furtiva de que es un gran no-no. (También tengo una sospecha furtiva de que no sé cómo deletrear "sospecha").

+1

Con respecto a su edición: Creo que lo que quiere hacer es simplemente bien. Un '$ values ​​['whatever']' inexistente saldrá como nulo y se convertirá en una cadena nula. El alcance de la supresión de errores es lo suficientemente limitado para que no oculte un error que debe ver. – awm

Respuesta

11

I recomiendan NUNCA usando el operador @. Alienta el código incorrecto y puede hacer que tu vida sea miserable cuando algo no funciona y estás tratando de depurarlo.

Por supuesto, puede desactivar avisos en php.ini, pero si yo fuera usted quisiera comenzar a usar isset() más :)

Usted puede hacer algo como esto:

echo '<input type="text" name="whatever" value="', (isset($values['whatever'])?$values['whatever']:''), '" />'; 

Puede leer más sobre lo horrible que es @, aquí: http://php.net/manual/en/language.operators.errorcontrol.php

Bueno, es el desencadenante de error real que es caro. Usar @ desencadena el error. La comprobación con isset() en cambio, no lo hace. http://seanmonstar.com/post/909029460/php-error-suppression-performance

+1

eso es verdad, tuve ese tipo de problema hoy cuando hago @ $ _ GET [sef :: VAR_NAME] y php no me dijo lo que estaba haciendo mal (¡¡no se !!!). – fabio

+0

Hola Fabio: si hace referencia a una variable de instancia dentro de su clase PHP, querrá usar esto: $ myValue = $ this-> VAR_NAME; Para ir junto con los carteles anteriores, esto sería suficiente: $ myValue = (isset ($ _ GET [$ this-> VAR_NAME]))? $ _GET [$ this-> VAR_NAME]: 'cadena vacía'; –

+0

La palabra clave SELF se usaría para hacer referencia a una función estática en su clase PHP (es decir, SELF :: quote_string ('quote this');) –

7

Para responder al título: La mejor manera es turn off display_errors.

Para lo que estás haciendo específicamente, usa isset().

Nota: Para aquellos que se quejan de que este 'apaga' todos los errores - from the PHP manual:

Ésta es una característica de apoyo para su desarrollo y nunca debe ser usado en sistemas de producción (p.ej. sistemas conectados a La Internet).

Después de la edición: Usted podría asegurarse de que las variables que se van a utilizar tienen algún valor (a ciegas haciéndose eco de un GET/POST var no es la mejor práctica) - o usted podría use un objeto para almacenar las variables que desea generar (como propiedades) y use __get() para devolver una cadena vacía (o una falsa) cuando la propiedad no se haya establecido.

Eso le dejaría con algo como:

echo $view->something; 
if($view->something){ 
    //stuff to do when something is set 
} 

creo que sería similar a lo que muchos de plantilla/view bibliotecas hacer.

Actualización: Noté esta respuesta antigua (ish), y pensé que se podría agregar algo. Para este caso de uso (donde los valores pueden o no pueden estar en una matriz), array_merge() podrían utilizarse:

$default = array('user' => false); 
$params = array_merge($default, $_GET); 
if($params['user']){ //safe to use, will have default value if not in $_GET 

} 
+2

, pero ¿y si solo quiere suprimir errores en partes específicas del guión? desactivar todos los errores no siempre es deseable. – fabio

+2

@fabio: Ocultar errores en una parte específica se llama "error";) Si piensas, que lo necesitas, de lo que realmente deberías pensar, que hay algo mal con esa parte. – KingCrunch

+1

@fabio: no está desactivando los errores, simplemente determina si los errores se deben imprimir en la pantalla o no. –

2

¿Por qué quiere suprimir algo, eso no ocurrirá, si comprueba la matriz antes de acceder a ella?

$something = array_key_exists('else', $_GET) ? $_GET['else'] : null; 
$something = isset($_GET['else']) ? $_GET['else'] : null; 

Su camino parece ser la solución para los perezosos.

Sin embargo, el operador @ nunca es una buena idea siempre que pueda evitarlo (y realmente hay muy poca situación, donde no puede evitarlo). También es bastanteperformante.

+0

'array_key_exists' no es útil para eso. Nunca habrá una clave presente con un valor de NULL. Son todas las cuerdas. – mario

+0

Estoy totalmente de acuerdo en que '@' debe evitarse en casi todos los casos, pero este es un ejemplo perfecto de cuándo ** y ** usar '@'. '$ something = @ $ _GET ['else']' es mucho más fácil de leer (imho) que las expresiones condicionales y produce el mismo resultado. – awm

+0

La parte de rendimiento es en realidad lo que me preocupó. – sdleihssirhc

1

Lo he dicho antes y estoy feliz de decir de nuevo:

$else = isset($_GET['else']) ? $_GET['else'] : null; 

es equivalente a:

$else = @$_GET["else"]; 

La diferencia es que uno es menos legible debido a la sal sintáctica para el error supresión, y el otro usa la función de lenguaje previsto para eso. También observe cómo en el segundo caso la notificación (muchas personas no comprenden la diferencia de los errores) aún puede ser descubierta por los controladores personalizados.

Para todos los propósitos prácticos, no debe usar ninguno. Use simplemente:

$else = $_GET["else"]; 

Desactive los avisos de depuración cuando no los necesite.

(Prácticamente estoy también por lo general usando el método tonto isset(). Pero estoy usando superglobales orientados a objetos, en lugar de estilo PHP4 $ _POST y $ _GET matrices, por lo que es sólo un isset oculta() y doesn' t contaminar mi código.)

0

Este es un problema común y aunque la solución es simple, tiene razón en que no es bonita. Personalmente me gusta usar envoltorios. Puede escribir fácilmente una clase simple que implemente ArrayAccess envolviendo la matriz pasada. Haría la verificación de clave internamente (en un lugar) y silenciosamente devolverá nulo cuando se le pida una clave inexistente. El resultado se ve así:

'bar')); var_dump ($ arr ['foo']); var_dump ($ arr ['zing']); // cadena (3) "barra" // NULL ?>

Esto también puede sentirse más familiar para usted, que viene de Javascript, como se puede añadir nuevas funcionalidades a la clase, así como la clasificación de encargo, o tal vez filtrando.

2

utilizar una función general de los accesos matriz:

/** 
* Function for accessing array elements and returning a 
* default value if the element is not set or null. 
* @param string $key Name of index 
* @param array $array Reference to an array 
* @param string $default Value to return if the key is not 
*  found in the array 
* @return mixed Value of array element (if it exists) or whatever 
*  is passed for default. 
*/ 
function element($key, &$a, $default = '') 
{ 
    if(array_key_exists($key, $a) && !is_null($a[$k])) 
    { 
     return $a[$key]; 
    } 
    return $default; 
} 

Entonces su salida HTML puede tener este aspecto:

echo '<input type="text" name="whatever" value="' 
    , element('whatever', $values), '" />' 
; 
Cuestiones relacionadas