Muitas vezes acontece comigo lidar com dados que podem ser uma matriz ou uma variável nula e alimentar alguns foreach
com esses dados.
$values = get_values();
foreach ($values as $value){
...
}
Ao alimentar um foreach com dados que não são uma matriz, você recebe um aviso:
Aviso: argumento inválido fornecido para foreach () em [...]
Supondo que não seja possível refatorar a get_values()
função para sempre retornar uma matriz (compatibilidade com versões anteriores, código-fonte não disponível, qualquer que seja o motivo), estou me perguntando qual é a maneira mais limpa e eficiente de evitar esses avisos:
- Transmitindo
$values
para matriz - Inicializando
$values
na matriz - Envolvendo o
foreach
com umif
- Outro (por favor, sugira)
$values
não seja uma matriz.Respostas:
Pessoalmente, acho que isso é o mais limpo - não tenho certeza se é o mais eficiente, mente!
A razão da minha preferência é que ela não aloca uma matriz vazia quando você não tem nada para começar.
fonte
count()
não é confiável. Se você passarcount()
nulo, ele retornará 0. Se você passar um argumento não nulo e sem matriz, retornará 1. Portanto, é impossível usarcount()
para determinar se a variável é uma matriz quando a variável pode ser uma matriz vazia, ou uma matriz contendo 1 item.if (is_array($values) || $values instanceof Traversable)
.Que tal este? muito mais limpo e tudo em linha única.
fonte
isset()
ouis_array()
ou ambos, dependendo inteiramente do seu cenário, etc. #Eu costumo usar uma construção semelhante a esta:
Observe que esta versão em particular não é testada, é digitada diretamente no SO a partir da memória.
Editar: adicionada verificação Traversable
fonte
$var instanceof Traversable
. Veja aqui . Porque, por exemplo, você pode buscar um SimpleXMLElement , mas não é uma instância do Iterator ou do IteratorAggregate.is_object($var)
re. php.net/manual/en/language.oop5.iterations.php #Iterator
ou implementadoIteratorAggregate
, mas é claro que isso é apenas minha opinião e, portanto, é subjetivo (nunca uso campos públicos).Por favor, não dependa da conversão como uma solução , mesmo que outros estejam sugerindo isso como uma opção válida para evitar um erro, isso pode causar outro.
Esteja ciente: se você espera que uma forma específica de matriz seja retornada, isso poderá falhar. Mais verificações são necessárias para isso.
Eu escrevi um teste rápido para apresentar esse problema . (Aqui está um teste de backup , caso o primeiro URL de teste falhe.)
Incluem-se testes para:
null
,false
,true
, umclass
, umarray
eundefined
.Sempre teste sua entrada antes de usá-la no foreach. Sugestões:
$array = is_array($var) or is_object($var) ? $var : [] ;
try{}catch(){}
blocosarray_key_exists
uma chave específica ou testar a profundidade de uma matriz (quando for uma!) .fonte
Tente o seguinte:
;)
fonte
O problema é sempre nulo e a fundição é de fato a solução de limpeza.
fonte
Antes de tudo, todas as variáveis devem ser inicializadas. Sempre.
A transmissão não é uma opção.
se get_values (); pode retornar variável de tipo diferente, esse valor deve ser verificado, é claro.
fonte
$array = (array)null;
uma matriz vazia. É claro que é um desperdício de alocação de memória ;-)Extensão mais concisa do código de @ Kris
especialmente para usar o código interno do modelo
fonte
return is_iterable($var) ? $var : array($var);
?Se você estiver usando o php7 e quiser lidar apenas com erros indefinidos, este é o IMHO mais limpo
fonte
Isso não verifica se é uma matriz, mas ignora o loop se a variável for nula ou vazia.
fonte
Não tenho certeza se esse é o caso, mas esse problema parece ocorrer várias vezes ao migrar sites wordpress ou sites dinâmicos em geral. Se esse for o caso, verifique se a hospedagem para a qual você está migrando usa a mesma versão PHP usada pelo site antigo.
Se você não está migrando seu site e este é apenas um problema que surgiu, tente atualizar para o PHP 5. Isso soluciona alguns desses problemas. Pode parecer uma solução boba, mas fez o truque para mim.
fonte
Ocorre um caso excepcional para este aviso se você definir a matriz como nula dentro do loop foreach
fonte
Que tal esta solução:
fonte
Argumento de aviso inválido fornecido para
foreach()
exibição de tweets. vá para/wp-content/plugins/display-tweets-php
. Em seguida, insira esse código na linha número 591, ele funcionará perfeitamente.fonte
if (is_array($_POST['auto'])){ // code }
Parece também haver uma relação com o meio ambiente:
Eu tive esse erro "argumento inválido fornecido foreach ()" apenas no ambiente de desenvolvimento, mas não no prod (estou trabalhando no servidor, não no host local).
Apesar do erro, um var_dump indicou que a matriz estava bem lá (nos dois casos, app e dev).
A
if (is_array($array))
volta doforeach ($array as $subarray)
resolveu o problema.Desculpe, mas não posso explicar a causa, mas como demorei um pouco para encontrar uma solução, pensei em compartilhar isso melhor como uma observação.
fonte
Use a função is_array quando passar o array para o loop foreach.
fonte
Que tal definir uma matriz vazia como fallback se
get_value()
estiver vazia?Não consigo pensar no caminho mais curto.
fonte
Vou usar uma combinação de
empty
,isset
eis_array
comofonte
eu faria o mesmo que Andy, mas usaria a função 'vazia'.
igual a:
fonte
$yourArray = 1;
ele tentar iterar, e você receberá o erro.empty()
Não é um teste adequado.