¿Por qué muchos desarrolladores de PHP odian usar isset () y / o cualquiera de las funciones defensivas similares de PHP como empty ()?

27

En stackoverflow, veo que este problema surge todo el tiempo:

Incluso Pekka (que ofrece muchos consejos sólidos de PHP) se ha enfrentado al temido E_NOTICEmonstruo y espera una mejor solución que usar isset(): isset () y empty () hacen que el código sea feo

Personalmente, uso isset()y empty()en muchos lugares para administrar el flujo de mis aplicaciones. Por ejemplo:

public function do_something($optional_parameter = NULL) {
    if (!empty($optional_parameter)) {
        // do optional stuff with the contents of $optional_parameter
    }
    // do mandatory stuff
}  

Incluso un fragmento simple como este:

if (!isset($_REQUEST['form_var'])) {
    // something's missing, do something about it.
}

Me parece muy lógico. No parece hinchado, parece un código estable. Pero muchos desarrolladores inician sus aplicaciones con E_NOTICElas habilitadas, descubren muchos avisos frustrantes de "índice de matriz no inicializados" y luego hacen una mueca ante la perspectiva de verificar variables definidas y "ensuciar" su código isset().

Supongo que otros idiomas manejan las cosas de manera diferente. Hablando por experiencia, JavaScript no es tan educado como PHP. Una variable indefinida típicamente detendrá la ejecución del script. Además, (hablando por inexperiencia ), estoy seguro de que lenguajes como C / C ++ simplemente se negarían a compilar.

Entonces, ¿los desarrolladores de PHP son simplemente vagos? (sin hablar de ti, Pekka, sé que estabas refactorizando una aplicación antigua). ¿O otros lenguajes manejan las variables indefinidas con más gracia que exigirle al programador que primero verifique si están definidas?

(Sé que hay otros E_NOTICEmensajes además de las variables indefinidas, pero esos parecen ser los que causan más disgusto)

Anexo
A partir de las respuestas hasta ahora, no soy el único que piensa que isset()no es un código inflado. Entonces, me pregunto, ¿hay problemas con los programadores en otros lenguajes que se hacen eco de este? ¿O es solo un problema de cultura PHP?

Stephen
fuente
44
Lamentablemente, he visto a los desarrolladores de php trabajar con "advertencias" desactivadas también.
Viper_Sb
Ay. Eso es triste
Stephen
1
No siendo un usuario de PHP, me pregunto: ¿por qué necesitaría verificar las variables indefinidas?
Winston Ewert
2
@ Winston: El problema con PHP (en contraste con muchos otros lenguajes) es que PHP permite muchas combinaciones de configuración. Por ejemplo, el programador puede decidir ignorar advertencias, avisos y notificaciones de desaprobación. Los desarrolladores más experimentados trabajarán con el conjunto de informes de error para informar todo. PHP también tiene muchas funciones que arrojan errores y devuelven códigos de estado en lugar de arrojar excepciones. Uno tiene que ser muy íntimo con el lenguaje para poder codificar de manera defensiva y exitosa. Muchos otros idiomas no permiten la elección. Estricto suele ser la opción predeterminada y única.
Wil Moore III
1
No me gusta isset () debido a la verbosidad que agrega. Una mejor forma de @ sería una buena alternativa.
Kzqai

Respuestas:

34

Codifico E_STRICTy nada más.

El uso de comprobaciones vacías e isset no hace que su código sea feo, sino que lo hace más detallado. En mi opinión, ¿qué es lo peor que puede pasar al usarlos? Escribo algunos caracteres más.

Versa las consecuencias de no usarlas, al menos advertencias.

Josh K
fuente
77
Mi entorno de desarrollo también lo es E_STRICT. Suprimo todos los errores en la producción, pero eso es solo para asegurar que nada se me haya pasado en el desarrollo.
Stephen
2
+1 Josh, soy igual. Cuando programa en E_STRICT, sabe que nunca tendrá sorpresas en su código. Única forma de volar, imo.
EricBoersma
3
@Stephen: siempre apague los errores de producción. Sin embargo, eso es solo una red de seguridad. El desarrollo debe (IMO) siempre ser E_STRICT. Escriba el código y resuelva todas las advertencias y errores.
Josh K
me estas repitiendo? :)
Stephen
@Stephen: estoy de acuerdo. :)
Josh K
17

Creo que los avisos sobre elementos desconocidos son un error de diseño en PHP. No estoy seguro de que sea posible corregir el error ahora, pero produce una gran cantidad de código repetitivo como if(isset($foo['abc']) && $foo['abc'] == '123'): este código no debería haberlo hecho isset, ya que la intención es verificar si hay '123' en cierto lugar $fooy si no hay nada allí, es Definitivamente no '123'. La única razón por la que tiene que escribir el doble de código es por este desafortunado error de diseño en PHP. Y desafortunadamente, los avisos son muy caros en PHP, por lo que deshabilitarlos no es una opción para el código donde el rendimiento es una preocupación.

Entonces sí, hace que el código sea feo en mi humilde opinión y me molesta. Y no es por falta de experiencia: uso PHP desde 1998 y recuerdo cuando había una .php3extensión y significaba "no es PHP 2". Tal vez soy flojo :) Pero la flojera, al menos cierto tipo, es una virtud para un programador.

Por otro lado, el uso válido de issety empty, al igual que los de la publicación original, está bien. Solo creo que PHP es demasiado celoso acerca de las advertencias en lugares donde isset/emptyrealmente no son necesarias.

StasM
fuente
3
Correcto. Es una cuestión de verbosidad. $eg = isset($_GET['eg'])? $_GET['eg'] : null;es ridículamente detallado. Realmente desearía que hubiera otro operador que no fuera "supresión de errores" per se para sustituir el significado corto de $eg = @$_GET['eg'];"aceptar-la-no-existencia-de-esta-matriz-clave-como-un-nulo". Tiendo a usar una función corta, en estos días.
Kzqai
77
Convenido. 4 años más tarde, ingrese al Operador de fusión nula: wiki.php.net/rfc/isset_ternary que nos da$eg = $_GET['eg'] ?? null;
Steve
O simplemente hazlo ahora con el operador de supresión de errores, por ejemplo $eg = @$_GET['eg'] ?: null;. Generalmente no lo uso, pero en este caso esperamos explícitamente ese error y decidimos ignorarlo. Es un carácter más largo que la unión nula y no es tan bueno (suprime todos los errores, y podría haber un ArrayAccess haciendo cosas funky allí, no solo una matriz), pero en general hace el trabajo.
El Yobo
12

Creo que PHP, como lenguaje gratuito, que se interpreta y utiliza en la web, tiene una proporción muy alta de codificadores no profesionales y no capacitados que no son completamente conscientes de por qué deberían codificar a la defensiva y solo ven las advertencias como otro error innecesario .

Escucho estos puntos de desarrolladores junior y programadores de guiones autodidactas todo el tiempo:

  • ¿Por qué inicializar una variable si llegará a existir de todos modos?
  • ¿Por qué verificar si algo existe antes de usarlo, indefinido equivale a falso de todos modos?
  • Si prefijo @ arregla mi código, ¿por qué complicar las cosas?

Si nunca han experimentado un lenguaje fuertemente tipado, o han experimentado las trampas de las variables no declaradas / desinstaladas, entonces son convincentes. Creo que generalmente ceden una vez que han experimentado el placer de depurar el código durante una hora más o menos para encontrar que era un error tipográfico en un nombre variable que causaba el problema.

El otro factor importante es el uso de PHP en la industria web, que tiende a estar mucho más preocupado por el rendimiento que la seguridad y la calidad del código.

Orbling
fuente
10
"Creo que PHP [...] tiene una proporción muy alta de codificadores no profesionales y no entrenados" Como desarrollador dedicado de PHP, no puedo estar más de acuerdo con usted. +1
Stephen
@Stephen Bueno, codifico principalmente en PHP y jQuery últimamente, aunque tengo educación formal, pero el código que ves como un profesional del que te haces responsable antes ... a veces desafía la creencia. ;-)
Orbling
1
Creo que es un problema real con PHP. Además de algunas peculiaridades en el lenguaje (que están resolviendo lentamente en cada nueva versión), hay un aire de amateurismo a su alrededor. Me imagino que ser un desarrollador profesional de PHP puede ser frustrante a veces, porque te comparan con 'el sobrino del jefe de la esquina'.
Erik van Brakel el
1
@Erik PHP era un pariente bastante pobre de Perl hace diez años, ahora es un lenguaje interpretado bastante razonable, particularmente para el uso web. Hay una razón por la cual compañías como Facebook lo usan. Pero como está disponible en todas partes, el set de aficionados lo usa ampliamente y esto empaña la reputación.
Orbling
5

Sí, son flojos. Muchos de todos modos ...

Desafortunadamente, la mentalidad de muchos codificadores de PHP es "No tiene sentido codificar a la defensiva si puede obtener el mismo resultado final más rápido confiando en el lenguaje para manejar los errores causados ​​por variables faltantes, etc." Lo sé, he trabajado con varios de ellos.

También tienden a ser los que misteriosamente se dirigen a un almuerzo temprano cuando su falta de manejo correcto de errores e informes elimina los servidores en vivo durante varias horas ...

Gruffputs
fuente
55
-1 para la opinión subjetiva sobre los codificadores PHP.
Josh K
44
@Josh, después de haber sido un codificador senior de PHP durante 4 años y medio y codificado PHP desde 1999, me temo que soy algo subjetivo. Debería haber calificado con "Por otro lado, los codificadores PHP más experimentados no son flojos y hacen las cosas correctamente" ...
Gruffputs
1
Eso deberías haberlo hecho.
Josh K
5

Intento evitar el uso de isset () y empty () evitando el uso de matrices como objetos de transferencia de datos. Cree una clase que se pueda configurar para aceptar un conjunto limitado de propiedades con valores predeterminados sanos y validar la entrada a esas propiedades. Incluso puede implementar la interfaz ArrayAccess para que pueda usarla como una matriz. Esto también le permite usar sugerencias de tipo en las firmas de su método para detectar errores cuando alguien intenta pasar el tipo de entidad incorrecto a su método.

Aneurisma9
fuente
Un enfoque muy interesante.
Toby
2

Una de las preguntas cuestionadas es la mía, así que permítanme reiterarlo.

Muchos desarrolladores confunden la presencia de muchos isset()como señal de calidad. Da una apariencia de confiabilidad y algunas personas lo consideran incluso como una característica de seguridad.

Pero debe tener en cuenta que PHP no es un lenguaje compilado. Es un lenguaje de script con un sistema de tipo dinámico. Los errores de E_NOTICE son solo errores por nombre. Y si issetse usan muchos con la única intención de suprimir los avisos, entonces en realidad solo está codificando contra el idioma .

Entonces, ¿los desarrolladores de PHP son simplemente vagos?

De hecho, ese es el caso si ve una gran cantidad de avisos y advertencias. A muchos novatos no les importan los avisos, y generalmente es el resultado de una discapacidad completa error_reporting(0).

Sin embargo, se equivoca al decir que otros desarrolladores no reconocieron las E_NOTICEs simplemente porque no estaban @ o no se suprimieron los activos. Al menos esa era mi intención detrás de la pregunta de retención de avisos . No son algo de lo que deshacerse, pero ocasionalmente información de depuración importante.

Como todas las generalizaciones, el uso desconsiderado de isset no conduce a un código óptimo. Es importante diferenciar dónde issety si emptyson necesarios y dónde están la sal sintáctica .

¿O es solo un problema de cultura PHP?

No, los "errores" de variables indefinidas no son solo un problema de PHP. Bash, TCL y Perl o JavaScript permiten el uso de variables indefinidas. Sin embargo, esta característica de lenguaje inmanente no se ve como un defecto allí. Hay construcciones de lenguaje similares para verificar valores indefinidos. Sin embargo, no se usan tan constantemente como en PHP, debido a que los valores undef no se caracterizan erróneamente como "error".

mario
fuente
1

Interesante. Casi nunca uso isset (). Mi código PHP rara vez se encuentra en un estado en el que no sé si una variable se ha configurado en primer lugar. Se accede a cada variable GET o POST utilizada a través de una función que le proporcionará un valor predeterminado si no existe. Los valores predeterminados en las llamadas a funciones generalmente se establecen explícitamente en 0 o cadenas vacías.

Gran maestro B
fuente
+1. Pasar a una función o método de clase es una buena solución. De hecho, me QUÉ hacer esto, pero en un apuro mis ejemplos anteriores todavía se ven limpios y poco hinchado a mí.
Stephen
0

Yo uso isset y vacío mucho. Pero principalmente son lugares que usted menciona, como el procesamiento $ _REQUEST, en caso de que alguien haya estado jugando con los parámetros. En los casos en que tengo control sobre todas las variables que vuelan, encuentro que generalmente no las necesito.

Tesserex
fuente
0

No me gusta usar isset, pero si hay masas de código hechas por otro, entonces puede ser una gracia salvadora. Escribí el código wee a continuación para ayudar con este problema, en lugar de usar isset () isseter ($ a, $ b) devolverá $ b si $ a no está definido o está vacío, o la función devuelve un valor nulo. Cualquier mejora, bienvenido:

//returns var or NULL (if undefined)
//$reserve optional second value is returned as $default if undefined
function isseter(&$default,&$reserve=NULL)
{
$default = isset($default) ? $default : NULL;
$reserve = isset($reserve) ? $reserve : NULL;
if ((!$default) && ($reserve)) $default=$reserve;
return $default;
}
bigal
fuente