Para os interessados, expandi este tópico em um pequeno artigo, que fornece as informações abaixo em uma forma um pouco melhor estruturada: O guia definitivo para isset do PHP e vazio
IMHO você deve pensar não apenas em tornar o aplicativo "compatível com E_NOTICE", mas em reestruturar tudo. Ter centenas de pontos em seu código que tentam regularmente usar variáveis inexistentes soa como um programa mal estruturado. Tentar acessar variáveis inexistentes nunca deveria acontecer, outras linguagens se recusam a isso em tempo de compilação. O fato de o PHP permitir que você faça isso não significa que você deva.
Esses avisos existem para ajudá- lo, não para incomodá-lo. Se você receber um aviso "Você está tentando trabalhar com algo que não existe!" , sua reação deve ser "Ops, que pena, deixe-me corrigir isso o mais rápido possível." De que outra forma você vai dizer a diferença entre "variáveis que funcionam muito bem indefinidas" e código honestamente errado que pode levar a erros graves ? Esta é também a razão pela qual você sempre, sempre , desenvolve com relatórios de erros voltados para 11 e continua plugando em seu código até que nenhumNOTICE
é emitido. Desativar o relatório de erros é apenas para ambientes de produção, para evitar vazamento de informações e fornecer uma melhor experiência do usuário, mesmo em caso de código com erros.
Para elaborar:
Você sempre precisará isset
ou empty
em algum lugar em seu código, a única maneira de reduzir sua ocorrência é inicializar suas variáveis corretamente. Dependendo da situação, existem diferentes maneiras de fazer isso:
Argumentos da função:
function foo ($bar, $baz = null) { ... }
Não há necessidade de verificar se $bar
ou $baz
estão definidos dentro da função porque você acabou de defini-los. Tudo o que você precisa se preocupar é se o valor deles é avaliado como true
ou false
(ou qualquer outra coisa).
Variáveis regulares em qualquer lugar:
$foo = null;
$bar = $baz = 'default value';
Inicialize suas variáveis no topo de um bloco de código no qual você irá usá-las. Isso resolve o !isset
problema, garante que suas variáveis sempre tenham um valor padrão conhecido, dá ao leitor uma ideia de como o código a seguir funcionará e, portanto, também serve como uma espécie de autodocumentação.
Matrizes:
$defaults = array('foo' => false, 'bar' => true, 'baz' => 'default value');
$values = array_merge($defaults, $incoming_array);
Da mesma forma que acima, você está inicializando o array com os valores padrão e os substituindo pelos valores reais.
Nos casos restantes, digamos um modelo em que você está gerando valores que podem ou não ser definidos por um controlador, você apenas terá que verificar:
<table>
<?php if (!empty($foo) && is_array($foo)) : ?>
<?php foreach ($foo as $bar) : ?>
<tr>...</tr>
<?php endforeach; ?>
<?php else : ?>
<tr><td>No Foo!</td></tr>
<?php endif; ?>
</table>
Se você está usando regularmente array_key_exists
, deve avaliar para que está usando. A única vez que faz diferença é aqui:
$array = array('key' => null);
isset($array['key']); // false
array_key_exists('key', $array); // true
Porém, conforme declarado acima, se você estiver inicializando corretamente suas variáveis, não precisa verificar se a chave existe ou não, porque você sabe que existe. Se você está recebendo a matriz a partir de uma fonte externa, o valor mais provável não será null
, mas ''
, 0
,'0'
, false
ou algo parecido, valor ou seja, um você pode avaliar com isset
ou empty
, dependendo da sua intenção. Se você definir regularmente uma chave de array para null
e quiser que signifique qualquer coisa menos false
, ou seja, se no exemplo acima os resultados divergentes isset
e array_key_exists
fizerem diferença para a lógica do seu programa, você deve se perguntar por quê. A mera existência de uma variável não deve ser importante, apenas seu valor deve ser relevante. Se a chave for um sinalizador true
/ false
, usetrue
ou false
não null
. A única exceção a isso seriam bibliotecas de terceiros que querem null
significar alguma coisa, mas como null
é tão difícil de detectar no PHP, ainda não encontrei nenhuma biblioteca que faça isso.