Por que muitos desenvolvedores PHP odeiam usar isset () e / ou qualquer uma das funções defensivas semelhantes do PHP como empty ()?


27

No stackoverflow, vejo esse problema surgir o tempo todo:

Até Pekka (que oferece muitos conselhos sólidos sobre PHP) esbarrou no E_NOTICEmonstro temido e esperava uma solução melhor do que usar isset(): isset () e empty () tornam o código feio

Pessoalmente, eu uso isset()e empty()em muitos lugares para gerenciar o fluxo de meus aplicativos. Por exemplo:

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

Mesmo um trecho simples como este:

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

parece muito lógico para mim. Não parece inchaço, parece código estável. Porém, muitos desenvolvedores acionam seus aplicativos com E_NOTICEo ativado, descobrem muitos avisos frustrantes de "índice de matriz não inicializado" e fazem caretas com a perspectiva de verificar as variáveis ​​definidas e "jogar lixo" no código isset().

Suponho que outros idiomas lidem com as coisas de maneira diferente. Falando por experiência própria, o JavaScript não é tão educado quanto o PHP. Uma variável indefinida normalmente interrompe a execução do script. Além disso, (falando por inexperiência ), tenho certeza de que linguagens como C / C ++ simplesmente se recusariam a compilar.

Então, os desenvolvedores PHP são preguiçosos? (sem falar de você, Pekka, eu sei que você estava refatorando um aplicativo antigo.) Ou outras linguagens lidam com variáveis ​​indefinidas mais graciosamente do que exigir que o programador verifique primeiro se elas estão definidas?

(Eu sei que existem outras E_NOTICEmensagens além de variáveis ​​indefinidas, mas essas parecem ser as que causam mais desgosto)

Adendo
Das respostas até agora, não sou o único que pensa que isset()não é um inchaço de código. Então, estou me perguntando agora, há problemas com programadores em outras linguagens que ecoam essa? Ou isso é apenas um problema de cultura PHP?


4
Infelizmente, vi devs php trabalharem com "avisos" desligados também.
Viper_Sb

Ai. Isso é triste.
19410 Stephen

1
Não sendo um usuário PHP, pergunto-me: por que você precisaria verificar variáveis ​​indefinidas?
Winston Ewert

2
@Winston: O problema com o PHP (em contraste com muitas outras linguagens) é que o PHP permite muitas combinações de configuração. Por exemplo, o programador pode decidir ignorar avisos, avisos e notificações de descontinuação. Desenvolvedores mais experientes trabalharão com o error_reporting definido para relatar tudo. O PHP também possui muitas funções que geram erros e retornam códigos de status, em vez de gerar exceções. É preciso ter muita intimidade com a linguagem para poder codificar defensivamente e com sucesso. Muitos outros idiomas não permitem a escolha. Estrito geralmente é a única opção padrão.
Wil Moore III

1
Não gosto de isset () por causa da verbosidade que ele adiciona. Uma melhor forma de @ seria uma boa alternativa.
Kzqai #

Respostas:


34

Eu codifico E_STRICTe nada mais.

Usar verificações vazias e de isset não torna seu código feio, mas torna seu código mais detalhado. Na minha opinião, qual é a pior coisa que pode acontecer ao usá-los? Eu digito mais alguns caracteres.

Versos as conseqüências de não usá-los, no mínimo avisos.


7
Meu ambiente de desenvolvimento também é E_STRICT. Eu suprimo todos os erros na produção, mas isso é apenas para garantir que nada me passe no desenvolvimento.
Stephen

2
Josh, eu sou do mesmo jeito. Quando você programa no E_STRICT, sabe que nunca terá surpresas no seu código. A única maneira de voar, imo.
EricBoersma

3
@ Stephen: Sempre desative os erros de produção. Isso é apenas uma rede de segurança. Desenvolvimento (IMO) sempre deve ser E_STRICT. Escreva o código e resolva todos os avisos e erros.
19410 Josh K

você está me imitando? :) #
Stephen

@ Stephen: Eu estou concordando. :)
Josh K

17

Eu acho que os avisos sobre elementos desconhecidos são um erro de design no PHP. Não tenho certeza se é possível corrigir o erro agora, mas ele produz um monte de código padrão if(isset($foo['abc']) && $foo['abc'] == '123')- esse código não deveria ter isset, pois a intenção é verificar se há '123' em determinado lugar $fooe se não há nada lá. definitivamente não é '123'. A única razão pela qual você precisa escrever o dobro do código existe por causa desse infeliz erro de design no PHP. E os avisos são muito caros em PHP, infelizmente, apenas desativá-los não é uma opção para o código em que o desempenho é uma preocupação.

Então, sim, isso torna o código IMHO feio e me irrita. E não é por falta de experiência - eu uso o PHP desde 1998 e lembro quando houve .php3extensão e isso significava "não é o PHP 2". Talvez eu seja preguiçoso :) Mas a preguiça - pelo menos certo tipo disso - é uma virtude para um programador.

Por outro lado, o uso válido de issete empty- assim como no post original - é bom. Eu apenas acho que o PHP é muito zeloso em relação a avisos em lugares onde isset/emptynão são realmente necessários.


3
Direita. É uma questão de verbosidade. $eg = isset($_GET['eg'])? $_GET['eg'] : null;é ridiculamente detalhado. Eu realmente gostaria que houvesse outro operador que não fosse "supressão de erro", em si, para substituir o breve significado de $eg = @$_GET['eg'];"aceitar a não-existência-desta-chave-da-matriz-como-nula". Atualmente, eu uso uma função curta.
Kzqai #

7
Acordado. 4 anos mais tarde, entrar no Coalesça Operador nulo: wiki.php.net/rfc/isset_ternary nos dando$eg = $_GET['eg'] ?? null;
Steve

Ou apenas faça isso agora com o operador de supressão de erros, por exemplo $eg = @$_GET['eg'] ?: null;. Geralmente não o uso, mas, neste caso, esperamos explicitamente esse erro e decidimos ignorá-lo. É um caractere mais longo que o nulo, e não é tão bom (suprime todos os erros, e pode haver um ArrayAccess fazendo coisas divertidas lá, não apenas um array), mas em geral ele faz o trabalho.
El Yobo 23/09

12

Acredito que o PHP, como uma linguagem livre, interpretada e usada na Web, tenha uma proporção muito alta de codificadores não profissionais e não treinados que não estejam totalmente cientes do motivo pelo qual devem codificar defensivamente e apenas ver os avisos como outro erro desnecessário. .

Eu ouço esses pontos de desenvolvedores juniores e codificadores de script autodidatas o tempo todo:

  • Por que inicializar uma variável se ela surgir de qualquer maneira?
  • Por que verificar se existe algo antes de usá-lo, indefinido equivale a falso de qualquer maneira?
  • Se prefixo com @, ele corrige meu código, por que complicar as coisas?

Se eles nunca experimentaram uma linguagem fortemente tipada, ou experimentaram as armadilhas das variáveis ​​não declaradas / não instanciadas, então são convincentes. Acho que eles geralmente cedem quando experimentam o prazer de depurar o código por uma hora ou mais para descobrir que foi um erro de digitação no nome de uma variável que está causando o problema.

O outro fator forte é o uso do PHP na indústria da web, que tende a se preocupar muito mais com a produtividade do que com a segurança e a qualidade do código.


10
"Eu acredito que o PHP [...] possui uma proporção muito alta de codificadores não profissionais e não treinados" Como desenvolvedor PHP dedicado, não posso concordar mais com você. +1
Stephen

@ Stephen Bem, eu codigo principalmente em PHP e jQuery ultimamente, embora eu tenha educação formal, mas o código que você vê como profissional e se torna responsável antes ... às vezes desafia a crença. ;-)
Orbling

1
Eu acho que é um problema real com o PHP. Além de algumas peculiaridades da linguagem (que elas estão resolvendo lentamente a cada nova versão), há um ar de amadorismo em torno dela. Eu posso imaginar que ser um desenvolvedor PHP profissional pode às vezes ser frustrante, porque você está sendo comparado ao 'sobrinho do chefe do outro lado da esquina'.
Erik van Brakel

1
O @Erik PHP era um parente relativamente pobre do Perl há dez anos; agora é uma linguagem interpretada razoavelmente razoável, principalmente para uso na web. Há uma razão pela qual empresas como o Facebook o usam. Mas, como está disponível em todos os lugares, o conjunto de amadores o utiliza extensivamente e isso prejudica a reputação.
Orbling 22/11/10

5

Sim, eles são preguiçosos. Muitos deles de qualquer maneira ...

Infelizmente, a mentalidade de muitos codificadores PHP é "Não faz sentido codificar defensivamente se você pode obter o mesmo resultado final mais rapidamente, contando com a linguagem para lidar com erros causados ​​por variáveis ​​ausentes, etc." Eu sei, eu trabalhei com vários deles.

Eles também costumam ser os que misteriosamente vão almoçar cedo, quando a falta de manipulação e relatórios corretos de erros retira os servidores ativos por várias horas ...


5
-1 para a opinião subjetiva sobre codificadores PHP.
Josh K

4
@ Josh, tendo sido um codificador PHP sênior por 4 anos e meio e codificado e ativado desde 1999, acho que sou um pouco subjetivo. Eu deveria ter me qualificado com "Por outro lado, os codificadores PHP mais experientes não são preguiçosos e fazem as coisas corretamente" ...
Gruffputs

1
Que você deveria ter.
Josh K

5

Tento evitar o uso de isset () e empty (), evitando o uso de matrizes como objetos de transferência de dados. Crie uma classe que possa ser configurada para aceitar um conjunto limitado de propriedades com padrões saudáveis ​​e validar a entrada para essas propriedades. Ele pode até implementar a interface ArrayAccess para que você possa usá-la como uma matriz. Isso também permite que você use dicas de tipo nas assinaturas do método para detectar erros quando alguém tenta passar o tipo errado de entidade para o método.


Uma abordagem muito interessante.
Toby

2

Uma das perguntas é a minha, então deixe-me reiterar.

Muitos desenvolvedores confundem a presença de muitos isset()como sinal de qualidade. Dá uma aparência de confiabilidade e algumas pessoas pensam nisso mesmo como um recurso de segurança.

Mas você deve levar em consideração que o PHP não é uma linguagem compilada. É uma linguagem de script com um sistema de tipos dinâmicos. Erros E_NOTICE são apenas erros por nome. E se muitos issetforem usados ​​com a única intenção de suprimir os avisos, na verdade você estará apenas codificando no idioma .

Então, os desenvolvedores PHP são preguiçosos?

Esse é realmente o caso se você ver uma abundância de avisos e avisos lançados. Muitos novatos não se importam com avisos, e geralmente é o resultado de uma pessoa completamente desativada error_reporting(0).

No entanto, você está enganado que outros desenvolvedores não reconheceram E_NOTICEs apenas porque não foram @ ou isset-suprimidos. Pelo menos essa era minha intenção por trás da questão dos avisos de retenção . Eles não são algo para se livrar, mas ocasionalmente informações importantes sobre depuração.

Como todas as generalizações, o uso indiferente do isset não leva ao código ideal. É importante diferenciar onde issete emptysão necessários e onde eles são sal sintático .

Ou isso é apenas um problema de cultura PHP?

Não, os "erros" variáveis ​​indefinidos não são apenas um problema de PHP. Bash, TCL e Perl ou JavaScript permitem o uso de variáveis ​​indefinidas. No entanto, esse recurso de linguagem imanente não é visto como defeito. Existem construções de linguagem semelhantes para verificar valores indefinidos. No entanto, eles não são tão usados ​​constantemente como no PHP, devido aos valores undef não serem descaracterizados como "erro".


1

Interessante. Eu quase nunca uso isset (). Meu código PHP raramente está em um estado em que não sei se uma variável foi definida em primeiro lugar. Toda variável GET ou POST usada é acessada por meio de uma função que fornecerá um padrão se não existir. Os valores padrão nas chamadas de função geralmente são explicitamente definidos como 0 ou cadeias vazias.


+1. Passar para uma função ou método de classe é uma boa solução. Na verdade, eu NÃO fazer isso, mas em uma pitada meus exemplos acima ainda olhar limpo e un-inchado para mim.
19410 Stephen

0

Eu uso o isset e esvazio bastante. Mas, na maioria das vezes, são os lugares que você menciona, como o processamento $ _REQUEST, caso alguém esteja mexendo nos parâmetros. Nos casos em que tenho controle sobre todas as variáveis ​​que circulam, acho que geralmente não preciso delas.


0

Eu não gosto de usar o isset, mas se houver uma grande quantidade de código feita por outro, pode ser uma graça salvadora. Eu escrevi o código pequenino abaixo para ajudar com esse problema, em vez de usar isset () isseter ($ a, $ b) retornará $ b se $ a não estiver definido ou vazio, ou a função retornará um valor nulo. Quaisquer melhorias, bem-vindo:

//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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.