“Aviso: variável indefinida”, “Aviso: índice indefinido” e “Aviso: deslocamento indefinido” usando PHP

1173

Estou executando um script PHP e continuo recebendo erros como:

Aviso: Variável indefinida: my_variable_name em C: \ wamp \ www \ mypath \ index.php na linha 10

Aviso: Índice indefinido: my_index C: \ wamp \ www \ mypath \ index.php na linha 11

As linhas 10 e 11 são assim:

echo "My variable value is: " . $my_variable_name;
echo "My index value is: " . $my_array["my_index"];

Qual é o significado dessas mensagens de erro?

Por que eles aparecem de repente? Eu costumava usar esse script há anos e nunca tive nenhum problema.

Como faço para corrigi-los?


Esta é uma pergunta de referência geral para as pessoas vincularem como duplicadas, em vez de precisar explicar o problema repetidamente. Eu sinto que isso é necessário porque a maioria das respostas do mundo real sobre esse assunto é muito específica.

Meta-discussão relacionada:

Pekka 웃
fonte
8
possível duplicata da Referência - O que esse erro significa no PHP?
meagar
3
a variável pode não ter sido inicializada. Você está inicializando a variável de uma postagem, get ou qualquer array? Se for esse o caso, você pode não ter um campo nessa matriz. Que você está acessando.
Anish Silwal
3
@Pekka 웃 - notei a edição adicionando o "e" Aviso: deslocamento indefinido "" - Não faria mais sentido usar "PHP:" Variável indefinida "," Índice indefinido "," Aviso de deslocamento indefinido "(até mesmo fora o PHP, uma vez que está marcado como "php". Além disso, o URL é cortado em and-notice-undef, apenas uma sugestão para que o URL não seja cortado. Talvez até removendo as (muitas) citações. OuPHP: “Undefined variable/index/offset” notices
Funk Quarenta Niner
2
@ Fred Acho que um argumento pode ser feito para ambas as variações. Há uma chance de que os novatos entrem na linha inteira, incluindo o "Aviso:" na consulta de pesquisa, que tenho certeza de que é o principal gerador de tráfego para essa pergunta. Se as mensagens estão lá na íntegra, que é susceptível de melhorar a visibilidade nos motores de busca
Pekka
2
@Pekka 웃 Eu entendo. Eu só disse isso porque o URL não foi cortado antes e agora é and-notice-undef. Foi apenas uma (poucas) sugestão (s). Apenas se repete também sendo Notice: Undefined.
Funk Quarenta Niner

Respostas:

1066

Aviso: variável indefinida

Da vasta sabedoria do Manual do PHP :

Confiar no valor padrão de uma variável não inicializada é problemático no caso de incluir um arquivo em outro que use o mesmo nome de variável. Também é um grande risco de segurança com o register_globals ativado. O erro de nível E_NOTICE é emitido no caso de trabalhar com variáveis ​​não inicializadas, mas não no caso de anexar elementos à matriz não inicializada. A construção de linguagem isset () pode ser usada para detectar se uma variável já foi inicializada. Além disso, e mais ideal é a solução de empty (), pois ela não gera um aviso ou mensagem de erro se a variável não for inicializada.

Da documentação do PHP :

Nenhum aviso será gerado se a variável não existir. Isso significa que vazio () é essencialmente o equivalente conciso a ! Isset ($ var) || $ var == false .

Isso significa que você pode usam apenas empty()para determinar se a variável é definida, e, além disso, verifica a variável contra o seguinte, 0, 0.0, "", "0", null, falseou [].

Exemplo:

$o = [];
@$var = ["",0,null,1,2,3,$foo,$o['myIndex']];
array_walk($var, function($v) {
    echo (!isset($v) || $v == false) ? 'true ' : 'false';
    echo ' ' . (empty($v) ? 'true' : 'false');
    echo "\n";
});

Teste o trecho acima no editor PHP online do 3v4l.org

Embora o PHP não exija uma declaração de variável, ele é recomendado para evitar algumas vulnerabilidades ou bugs de segurança nos quais se esqueça de atribuir um valor a uma variável que será usada posteriormente no script. O que o PHP faz no caso de variáveis ​​não declaradas emite um erro de nível muito baixo E_NOTICE, que nem é relatado por padrão, mas o Manual recomenda que isso seja permitido durante o desenvolvimento.

Maneiras de lidar com o problema:

  1. Recomendado: declare suas variáveis, por exemplo, quando você tenta anexar uma sequência a uma variável indefinida. Ou use isset()/ !empty() para verificar se eles são declarados antes de fazer referência a eles, como em:

    //Initializing variable
    $value = ""; //Initialization value; Examples
                 //"" When you want to append stuff later
                 //0  When you want to add numbers later
    //isset()
    $value = isset($_POST['value']) ? $_POST['value'] : '';
    //empty()
    $value = !empty($_POST['value']) ? $_POST['value'] : '';

    Isso ficou muito mais limpo a partir do PHP 7.0, agora você pode usar o operador de coalescência nula :

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
  2. Defina um manipulador de erro personalizado para E_NOTICE e redirecione as mensagens para longe da saída padrão (talvez para um arquivo de log):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
  3. Desative E_NOTICE dos relatórios. Uma maneira rápida de excluir apenas E_NOTICEé:

    error_reporting( error_reporting() & ~E_NOTICE )
  4. Suprima o erro com o operador @ .

Nota: é altamente recomendável implementar apenas o ponto 1.

Aviso: Índice indefinido / deslocamento indefinido

Este aviso aparece quando você (ou PHP) tenta acessar um índice indefinido de uma matriz.

Maneiras de lidar com o problema:

  1. Verifique se o índice existe antes de acessá-lo. Para isso, você pode usar isset()ou array_key_exists():

    //isset()
    $value = isset($array['my_index']) ? $array['my_index'] : '';
    //array_key_exists()
    $value = array_key_exists('my_index', $array) ? $array['my_index'] : '';
  2. A construção da linguagem list()pode gerar isso quando tenta acessar um índice de matriz que não existe:

    list($a, $b) = array(0 => 'a');
    //or
    list($one, $two) = explode(',', 'test string');

Duas variáveis ​​são usadas para acessar dois elementos da matriz, no entanto, existe apenas um elemento da matriz, índice 0, portanto, isso irá gerar:

Aviso: deslocamento indefinido: 1

$_POST/ $_GET/ $_SESSIONVariável

Os avisos acima aparecem frequentemente ao trabalhar com $_POST, $_GETou $_SESSION. Para $_POSTe $_GETvocê apenas precisa verificar se o índice existe ou não antes de usá-los. Para $_SESSIONvocê ter certeza de que a sessão foi iniciada session_start()e que o índice também existe.

Observe também que todas as 3 variáveis ​​são superglobais e estão em maiúsculas.

Relacionado:

Rizier123
fonte
7
@ dieselpower44 Alguns pensamentos: O "operador de desligamento" ( @) apresenta alguns problemas de desempenho. Além disso, como suprime todos os erros dentro de um escopo específico, usá-lo sem cuidado pode mascarar as mensagens que você deseja ter visto.
IMSoP
6
Ocultar os problemas NÃO é a maneira de lidar com eles. Os itens 2 ... 4 podem ser usados ​​apenas em servidores de produção, e não em geral.
Salman A
1
É possível desligar a mensagem em linha (não no manipulador) quando também é usado um manipulador de erro personalizado? $var = @$_GET['nonexisting'];ainda causa aviso ..
Alph.Dev 11/10
18
Por que é recomendável usar 1. em $value = isset($_POST['value']) ? $_POST['value'] : '';vez de usar 4. $value = @$_POST['value'];?
Forsvunnet
@twistedpixel Essas 4 maneiras são independentes, isso não é um guia de quatro etapas. Portanto, se você optou por usar a maneira 4, isso significa que você não implementou as três primeiras maneiras, portanto ainda não suprimiu nenhum erro.
Aycan Yaşıt
141

Tente esse

Q1: este aviso significa que $ varname não está definido no escopo atual do script.

P2: O uso das condições isset (), empty () antes de usar qualquer variável suspeita funciona bem.

// recommended solution for recent PHP versions
$user_name = $_SESSION['user_name'] ?? '';

// pre-7 PHP versions
$user_name = '';
if (!empty($_SESSION['user_name'])) {
     $user_name = $_SESSION['user_name'];
}

Ou, como uma solução rápida e suja:

// not the best solution, but works
// in your php setting use, it helps hiding site wide notices
error_reporting(E_ALL ^ E_NOTICE);

Nota sobre as sessões:

Ish
fonte
Se estiver usando E_NOTICEdo php.iniarquivo de configuração, façaerror_reporting = (E_ALL & ~E_NOTICE)
ahmd0 4/04
A partir da resposta acima, tentei o isset, array_key_exists, mas esses não funcionaram. Eu tentei sua resposta, .empty (), e funciona. Muito obrigado!
ewef 24/04
63

Operador de exibição de erro@

Para avisos indesejados e redundantes, pode-se usar o @operador dedicado para ocultar mensagens de índice / variável indefinidas.

$var = @($_GET["optional_param"]);
  • Isso geralmente é desencorajado. Os recém-chegados tendem a usar demais.
  • É muito inapropriado para código dentro da lógica da aplicação (ignorando variáveis ​​não declaradas onde você não deveria), por exemplo, para parâmetros de função ou em loops.
  • Há uma cabeça sobre o isset?:ou ??super-supressão no entanto. Os avisos ainda podem ser registrados. E pode-se ressuscitar @avisos ocultos com:set_error_handler("var_dump");
    • Além disso, você não deve usar / recomendar habitualmente if (isset($_POST["shubmit"]))no seu código inicial.
    • Os recém-chegados não identificarão tais erros. Apenas o priva dos Avisos do PHP para esses mesmos casos. Adicione @ou issetsomente após verificar a funcionalidade.
    • Corrija a causa primeiro. Não são os avisos.

  • @é principalmente aceitável para $_GET/ $_POSTparâmetros de entrada, especificamente se eles são opcionais .

E como isso abrange a maioria dessas perguntas, vamos expandir as causas mais comuns:

$_GET/ $_POST/ $_REQUESTentrada indefinida

  • A primeira coisa que você faz ao encontrar um índice / deslocamento indefinido é verificar erros de digitação:
    $count = $_GET["whatnow?"];

    • Esse é um nome de chave esperado e está presente em cada solicitação de página?
    • Nomes de variáveis e indicações de matriz diferenciam maiúsculas de minúsculas no PHP.
  • Em segundo lugar, se o aviso não tiver uma causa óbvia, use var_dumpou print_rpara verificar todas as matrizes de entrada quanto ao seu conteúdo atual:

    var_dump($_GET);
    var_dump($_POST);
    //print_r($_REQUEST);

    Ambos irão revelar se o seu script foi chamado com os parâmetros certos ou certos.

  • Como alternativa ou adicionalmente use o devtools ( F12) do navegador e inspecione a guia de rede em busca de solicitações e parâmetros:

    ferramentas do desenvolvedor do navegador / guia rede

    Os parâmetros POST e entrada GET serão mostrados separadamente.

  • Para $_GETparâmetros que você também pode espiada no QUERY_STRINGem

    print_r($_SERVER);

    O PHP possui algumas regras para agrupar nomes de parâmetros não padrão nos superglobais. O Apache também pode reescrever. Você também pode examinar os $_COOKIEScabeçalhos de solicitação HTTP brutos e outros fornecidos dessa maneira.

  • Obviamente, observe os parâmetros GET na barra de endereços do navegador :

    http://example.org/script.php?id=5&sort=desc

    Os name=valuepares após o ?ponto de interrogação são os parâmetros da sua consulta (GET). Portanto, esse URL só poderia gerar $_GET["id"]e $_GET["sort"].

  • Por fim, verifique suas declarações <form>e<input> , se você espera um parâmetro, mas não recebe nenhum.

    • Certifique-se de que cada entrada necessária tenha um <input name=FOO>
    • O atributo id=ou title=não é suficiente.
    • Um method=POSTformulário deve ser preenchido $_POST.
    • Enquanto a method=GET(ou deixando de fora) produziria $_GETvariáveis.
    • Também é possível que um formulário forneça action=script.php?get=paramvia $ _GET e os method=POSTcampos restantes em $ _POST ao lado.
    • Com as configurações modernas do PHP (≥ 5.6), tornou-se viável (não está na moda) usar $_REQUEST['vars']novamente, o que esmaga os parâmetros GET e POST.
  • Se você estiver usando o mod_rewrite, verifique os parâmetros access.loge ative os RewriteLogparâmetros ausentes.

$_FILES

  • As mesmas verificações de integridade se aplicam a uploads de arquivos e $_FILES["formname"].
  • Além disso, verifique enctype=multipart/form-data
  • Bem como method=POSTna sua <form>declaração.
  • Veja também: Erro de índice indefinido do PHP $ _FILES?

$_COOKIE

  • A $_COOKIEmatriz nunca é preenchida logo após setcookie(), mas apenas em qualquer solicitação HTTP de acompanhamento.
  • Além disso, o tempo limite de validade pode ser restrito a subdomínios ou caminhos individuais, e o usuário e o navegador podem apenas rejeitá-los ou excluí-los.
mario
fonte
2
Se você está curioso para saber qual é o impacto no desempenho, este artigo resume bem, derickrethans.nl/… .
Gajus
@GajusKuizinas Houve algumas mudanças desde 2009, em particular o php.net/ChangeLog-5.php#5.4.0 altera o resultado drasticamente (consulte "Zend Engine, performance" e "(silencio) operator").
mario
Obrigado @ mario, interessante. Agora, se alguém foi bom o suficiente para avaliar os dois ... 3v4l.org/CYVOn/perf#tabs 3v4l.org/FLp3D/perf#tabs De acordo com este teste, parece ser idêntico (observe que a escala muda).
Gajus 11/02
47

Geralmente por causa de "programação ruim" e possibilidade de erros agora ou mais tarde.

  1. Se houver algum erro, faça uma atribuição apropriada para a variável primeiro: $ varname = 0;
  2. Se realmente for definido apenas algumas vezes, teste-o: if (isset($varname))antes de usá-lo
  3. Se é porque você digitou errado, corrija
  4. Talvez até ative os avisos nas configurações do PHP
Erik
fonte
5
Por favor, não desligue os avisos. Em linguagens mais estritas, elas geralmente significam "pode ​​haver um erro, é melhor verificar essa linha duas vezes" - em uma linguagem tão permissiva quanto o PHP, elas geralmente significam "esse código é uma porcaria e propriamente repleto de bugs; vou tentar fazer algum sentido, mas é melhor você corrigir isso o mais rápido possível ".
5
Embora eu concorde com os três primeiros pontos, o nº 4 está simplesmente errado. Ocultar um problema não o fará desaparecer e pode até causar mais problemas no caminho.
Valentin Flachsel
1
@Freek absolutamente verdadeiro, mas em alguns cenários (o script comprado, zero conhecimento técnico, precisa ser executado até amanhã ...) é a solução em fita adesiva - muito ruim, que sempre precisa ser enfatizada, mas uma opção
Pekka
Fita adesiva é boa ... às vezes. Historicamente, os avisos foram desativados nas configurações padrão do PHP, mas as configurações padrão se tornaram mais rigorosas. Pena que muitos voltem às configurações antigas, para não incomodar os clientes.
Erik
41

Isso significa que você está testando, avaliando ou imprimindo uma variável à qual ainda não atribuiu nada. Isso significa que você tem um erro de digitação ou precisa verificar se a variável foi inicializada para algo primeiro. Verifique seus caminhos lógicos, eles podem estar definidos em um caminho, mas não em outro.

DGM
fonte
34

Não queria desativar o aviso porque é útil, mas queria evitar muita digitação.

Minha solução foi esta função:

function ifexists($varname)
{
  return(isset($$varname)?$varname:null);
}

Então, se eu quiser fazer referência a $ name e eco, se existir, simplesmente escrevo:

<?=ifexists('name')?>

Para elementos da matriz:

function ifexistsidx($var,$index)
{
  return(isset($var[$index])?$var[$index]:null);
}

Na página, se eu quiser me referir a $ _REQUEST ['name']:

<?=ifexistsidx($_REQUEST,'name')?>
Ferenci Zoltán László
fonte
2
Sua função ifexists () não funciona para mim no PHP 5.3. As variáveis ​​do chamador não estão disponíveis no escopo local da função (consulte Escopo variável ), a menos que sejam Superglobais ou você mexa com $ GLOBALS , portanto $foo = "BABAR"; ifexists('foo');, em geral, retornará nulo. (Os itálicos são capítulos do php.net.)
skierpage 19/06/12
agora você receberá "olá de" ... qual é o sentido? basta verificar o valorif( !empty($user) and !empty($location) ) echo "hello $user ..."
gcb
27

A melhor maneira de obter a string de entrada é:

$value = filter_input(INPUT_POST, 'value');

Esse one-liner é quase equivalente a:

if (!isset($_POST['value'])) {
    $value = null;
} elseif (is_array($_POST['value'])) {
    $value = false;
} else {
    $value = $_POST['value'];
}

Se você deseja absolutamente um valor de string , assim como:

$value = (string)filter_input(INPUT_POST, 'value');
mpyw
fonte
25

É porque a variável '$ user_location' não está sendo definida. Se você estiver usando um loop if dentro do qual está declarando a variável '$ user_location', também deverá ter um loop else e definir o mesmo. Por exemplo:

$a=10;
if($a==5) { $user_location='Paris';} else { }
echo $user_location;

O código acima criará um erro como O loop if não é satisfeito e no loop else '$ user_location' não foi definido. Ainda foi solicitado ao PHP que ecoasse a variável. Portanto, para modificar o código, você deve fazer o seguinte:

$a=10;
if($a==5) { $user_location='Paris';} else { $user_location='SOMETHING OR BLANK'; }
echo $user_location;
Roger
fonte
25

Em resposta a "" Por que eles aparecem de repente? Eu costumava usar esse script há anos e nunca tive nenhum problema. "

É muito comum a maioria dos sites operar sob o relatório de erro "padrão" de "Mostrar todos os erros, mas não 'avisos' e 'obsoletos'". Isso será definido no php.ini e será aplicado a todos os sites no servidor. Isso significa que os "avisos" usados ​​nos exemplos serão suprimidos (ocultos), enquanto outros erros, considerados mais críticos, serão mostrados / registrados.

A outra configuração crítica é que os erros podem ser ocultos (ou seja, display_errorsdefinidos como "off" ou "syslog").

O que aconteceu neste caso é que o error_reportingfoi alterado para também mostrar avisos (conforme exemplos) e / ou que as configurações foram alteradas paradisplay_errors na tela (em vez de suprimi-las / registrá-las).

Por que eles mudaram?

A resposta óbvia / mais simples é que alguém ajustou uma dessas configurações no php.ini ou uma versão atualizada do PHP agora está usando um php.ini diferente de antes. Esse é o primeiro lugar para procurar.

No entanto, também é possível substituir essas configurações em

  • .htconf (configuração do servidor da web, incluindo vhosts e subconfigurações) *
  • .htaccess
  • no próprio código php

e qualquer um desses também poderia ter sido alterado.

Há também a complicação adicional de que a configuração do servidor da web pode ativar / desativar as diretivas .htaccess, portanto, se você tiver diretivas no .htaccess que de repente iniciem / parem de funcionar, será necessário verificar isso.

(.htconf / .htaccess supõe que você esteja executando como apache. Se a linha de comando não estiver sendo aplicada, se estiver executando o IIS ou outro servidor da Web, será necessário verificar essas configurações de acordo)

Sumário

  • As diretivas de verificação error_reportinge display_errorsphp no php.ini não foram alteradas ou você não está usando um php.ini diferente de antes.
  • As diretivas de verificação error_reportinge display_errorsphp no .htconf (ou vhosts etc.) não foram alteradas
  • As diretivas de verificação error_reportinge display_errorsphp em .htaccess não foram alteradas
  • Se você possui uma diretiva em .htaccess, verifique se eles ainda são permitidos no arquivo .htconf
  • Por fim, verifique seu código; possivelmente uma biblioteca não relacionada; para ver se as diretivas error_reportinge display_errorsphp foram definidas lá.
Robbie
fonte
20

a solução rápida é atribuir sua variável a null na parte superior do seu código

$user_location = null;
Shahin Mammadzada
fonte
16

Eu costumava amaldiçoar esse erro, mas pode ser útil lembrá-lo de como escapar da entrada do usuário.

Por exemplo, se você achou que era um código inteligente, abreviado:

// Echo whatever the hell this is
<?=$_POST['something']?>

...Pense de novo! Uma solução melhor é:

// If this is set, echo a filtered version
<?=isset($_POST['something']) ? html($_POST['something']) : ''?>

(Eu uso uma html()função personalizada para escapar de caracteres, sua milhagem pode variar)

rybo111
fonte
15

Agora, no PHP 7.0, é possível usar o operador coalescente nulo:

echo "My index value is: " . ($my_array["my_index"] ?? '');

Igual a:

echo "My index value is: " . (isset($my_array["my_index"]) ? $my_array["my_index"] : '');

Manual do PHP PHP 7.0

elpiel
fonte
Isso também funciona bem nas instruções if. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
um codificador
Seu código é realmente um bom bug negligenciado: ?? - apenas verifica isset()se você passa is_array()- que é um comportamento booleano e inesperado.
Elpiel
14

Eu uso todo o tempo própria função útil exst () que declara automaticamente variáveis.

Seu código será -

$greeting = "Hello, ".exst($user_name, 'Visitor')." from ".exst($user_location);


/** 
 * Function exst() - Checks if the variable has been set 
 * (copy/paste it in any place of your code)
 * 
 * If the variable is set and not empty returns the variable (no transformation)
 * If the variable is not set or empty, returns the $default value
 *
 * @param  mixed $var
 * @param  mixed $default
 * 
 * @return mixed 
 */

function exst( & $var, $default = "")
{
    $t = "";
    if ( !isset($var)  || !$var ) {
        if (isset($default) && $default != "") $t = $default;
    }
    else  {  
        $t = $var;
    }
    if (is_string($t)) $t = trim($t);
    return $t;
}
user2253362
fonte
14

Em uma linguagem muito simples .
O erro é que você está usando uma variável $user_locationque não foi definida por você anteriormente e que não tem nenhum valor. Portanto, recomendo que você declare essa variável antes de usá- la. Por exemplo:


$user_location = '';
Ou
$user_location = 'Los Angles';
Este é um erro muito comum que você pode enfrentar. Portanto, não se preocupe, basta declarar a variável e Apreciar codificação .

Rishabh Seth
fonte
8

por que não manter as coisas simples?

<?php
error_reporting(E_ALL); // making sure all notices are on

function idxVal(&$var, $default = null) {
         return empty($var) ? $var = $default : $var;
  }

echo idxVal($arr['test']);         // returns null without any notice
echo idxVal($arr['hey ho'], 'yo'); // returns yo and assigns it to array index, nice

?>
gts
fonte
8

POR QUE ISSO ESTÁ ACONTECENDO?

Com o tempo, o PHP se tornou uma linguagem mais focada na segurança. As configurações que costumavam ser desativadas por padrão agora estão ativadas por padrão. Um exemplo perfeito disso é E_STRICT, que foi ativado por padrão a partir do PHP 5.4.0 .

Além disso, de acordo com a documentação do PHP, por padrão, E_NOTICEestá desativado no php.ini. Os documentos do PHP recomendam ativá-lo para fins de depuração . No entanto, quando faço o download do PHP no repositório Ubuntu - e na pilha do BitNami no Windows - vejo outra coisa.

; Common Values:
;   E_ALL (Show all errors, warnings and notices including coding standards.)
;   E_ALL & ~E_NOTICE  (Show all errors, except for notices)
;   E_ALL & ~E_NOTICE & ~E_STRICT  (Show all errors, except for notices and coding standards warnings.)
;   E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR  (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

Observe que, error_reportingna verdade, está definido como o valor da produção por padrão, e não como o valor "padrão" por padrão. Isso é um pouco confuso e não está documentado fora do php.ini, por isso não validei isso em outras distribuições.

Para responder sua pergunta, no entanto, esse erro é exibido agora quando não era exibido antes porque:

  1. Você instalou o PHP e as novas configurações padrão estão um pouco mal documentadas, mas não as excluem E_NOTICE.

  2. E_NOTICEavisos como variáveis ​​indefinidas e índices indefinidos realmente ajudam a tornar seu código mais limpo e seguro. Posso dizer-lhe que, anos atrás, manter E_NOTICEativado me forçou a declarar minhas variáveis. Tornou muito mais fácil aprender C, não declarar variáveis ​​é muito maior do que um incômodo.

O QUE POSSO FAZER SOBRE ISSO?

  1. Desative E_NOTICEcopiando o "Valor padrão" E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATEDe substituindo-o pelo que atualmente não é comentado após a entrada de iguais error_reporting =. Reinicie o Apache ou PHP se estiver usando CGI ou FPM. Certifique-se de editar o php.ini "certo". O correto será o Apache se você estiver executando o PHP com Apache, fpm ou php-fpm se estiver executando o PHP-FPM, cgi se estiver executando o PHP-CGI, etc. Este não é o método recomendado, mas se você tiver um código legado ser extremamente difícil de editar, pode ser sua melhor aposta.

  2. Desative E_NOTICEo nível de arquivo ou pasta. Isso pode ser preferível se você tiver algum código legado, mas desejar fazer as coisas da maneira "certa", caso contrário. Para fazer isso, você deve consultar o Apache2, o Nginx ou qualquer que seja o servidor de sua escolha. No Apache, você usariaphp_value dentro do <Directory>.

  3. Reescreva seu código para ficar mais limpo. Se você precisar fazer isso enquanto estiver migrando para um ambiente de produção ou não quiser que alguém veja seus erros, verifique se está desabilitando qualquer exibição de erros e registrando apenas seus erros (consulte display_errorse log_errorsem php.ini e configurações do servidor) .

Para expandir a opção 3: este é o ideal. Se você pode seguir este caminho, você deve. Se você não seguir esta rota inicialmente, considere mover essa rota eventualmente testando seu código em um ambiente de desenvolvimento. Enquanto você está nisso, livre-se ~E_STRICTe ~E_DEPRECATEDveja o que pode dar errado no futuro. Você verá muitos erros desconhecidos, mas impedirá que você tenha problemas desagradáveis ​​quando precisar atualizar o PHP no futuro.

O QUE SIGNIFICA ERROS?

Undefined variable: my_variable_name- Isso ocorre quando uma variável não foi definida antes do uso. Quando o script PHP é executado, internamente, apenas assume um valor nulo. No entanto, em qual cenário você precisaria verificar uma variável antes de ser definida? Por fim, esse é um argumento para "código desleixado". Como desenvolvedor, posso dizer que adoro quando vejo um projeto de código aberto no qual as variáveis ​​são definidas no escopo mais alto possível. Isso facilita a identificação de quais variáveis ​​serão exibidas no futuro e a leitura / aprendizagem do código.

function foo()
{
    $my_variable_name = '';

    //....

    if ($my_variable_name) {
        // perform some logic
    }
}

Undefined index: my_index- Isso ocorre quando você tenta acessar um valor em uma matriz e ele não existe. Para evitar esse erro, execute uma verificação condicional.

// verbose way - generally better
if (isset($my_array['my_index'])) {
    echo "My index value is: " . $my_array['my_index'];
}

// non-verbose ternary example - I use this sometimes for small rules.
$my_index_val = isset($my_array['my_index'])?$my_array['my_index']:'(undefined)';
echo "My index value is: " . $my_index_val;   

Outra opção é declarar uma matriz vazia na parte superior da sua função. Isto nem sempre é possível.

$my_array = array(
    'my_index' => ''
);

//...

$my_array['my_index'] = 'new string';

(dica adicional)

  • Quando encontrei esses e outros problemas, usei o NetBeans IDE (gratuito) e ele me deu uma série de avisos e avisos. Alguns deles oferecem dicas muito úteis. Isso não é um requisito e eu não uso mais IDEs, exceto em grandes projetos. Hoje sou mais uma vimpessoa :).
smcjones
fonte
6

índice indefinido significa em uma matriz que você solicitou o índice de matriz indisponível, por exemplo

<?php 

$newArray[] = {1,2,3,4,5};
print_r($newArray[5]);

?>

variável indefinida significa que você usou uma variável completamente inexistente ou que não está definida ou inicializada com esse nome, por exemplo

<?php print_r($myvar); ?>

deslocamento indefinido significa na matriz que você solicitou uma chave inexistente. E a solução para isso é verificar antes de usar

php> echo array_key_exists(1, $myarray);
Sintayehu Abaynhe
fonte
4

Em relação a esta parte da pergunta:

Por que eles aparecem de repente? Eu costumava usar esse script há anos e nunca tive nenhum problema.

Não há respostas definidas, mas aqui estão algumas explicações possíveis de por que as configurações podem mudar "repentinamente":

  1. Você atualizou o PHP para uma versão mais recente que pode ter outros padrões para reportagem de erros, display_errors ou outras configurações relevantes.

  2. Você removeu ou introduziu algum código (possivelmente em uma dependência) que define configurações relevantes em tempo de execução usando ini_set()ou error_reporting()(procure-as no código)

  3. Você alterou a configuração do servidor da web (assumindo o apache aqui): as .htaccessconfigurações de arquivos e vhost também podem manipular as configurações de php.

  4. Normalmente, os avisos não são exibidos / relatados (consulte o manual do PHP ), portanto, é possível que, ao configurar o servidor, o arquivo php.ini não possa ser carregado por algum motivo (permissões de arquivo ??) e você estivesse nas configurações padrão . Posteriormente, o 'bug' foi resolvido (por acidente) e agora pode carregar o arquivo php.ini correto com o error_reporting definido para mostrar avisos.

Wouter de Winter
fonte
3

Se estiver trabalhando com classes, certifique-se de referenciar variáveis ​​de membro usando $this:

class Person
{
    protected $firstName;
    protected $lastName;

    public function setFullName($first, $last)
    {
        // Correct
        $this->firstName = $first;

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}
John Conde
fonte
3

Outro motivo pelo qual um aviso de índice indefinido será lançado é que uma coluna foi omitida de uma consulta ao banco de dados.

Ou seja:

$query = "SELECT col1 FROM table WHERE col_x = ?";

Em seguida, tentando acessar mais colunas / linhas dentro de um loop.

Ou seja:

print_r($row['col1']);
print_r($row['col2']); // undefined index thrown

ou em um whileloop:

while( $row = fetching_function($query) ) {

    echo $row['col1'];
    echo "<br>";
    echo $row['col2']; // undefined index thrown
    echo "<br>";
    echo $row['col3']; // undefined index thrown

}

Outra coisa que precisa ser notada é que, em um * NIX OS e Mac OS X, as coisas diferenciam maiúsculas de minúsculas.

Consulte as seguintes perguntas e respostas na pilha:

Fred -ii-
fonte
3

O uso de um ternário é simples, legível e limpo:

Antes do PHP 7
Atribua uma variável ao valor de outra variável, se estiver configurada; caso contrário, atribuanull(ou qualquervalor padrão que você precise):

$newVariable = isset($thePotentialData) ? $thePotentialData : null;

PHP 7+
O mesmo, exceto usando o Null Coalescing Operator . Não há mais a necessidade de chamar, isset()pois isso é incorporado e não é necessário fornecer a variável para retornar, pois supõe-se que retorne o valor da variável que está sendo verificada:

$newVariable = $thePotentialData ?? null;

Ambos interromperão os avisos da pergunta OP e ambos são o equivalente exato de:

if (isset($thePotentialData)) {
    $newVariable = $thePotentialData;
} else {
    $newVariable = null;
}

 
Se você não precisar definir uma nova variável, poderá usar diretamente o valor retornado do ternário, como com echo, argumentos de função, etc:

Eco:

echo 'Your name is: ' . isset($name) ? $name : 'You did not provide one';

Função:

$foreName = getForeName(isset($userId) ? $userId : null);

function getForeName($userId)
{
    if ($userId === null) {
        // Etc
    }
}

O exemplo acima funcionará da mesma forma com matrizes, incluindo sessões, etc., substituindo a variável que está sendo verificada por, por exemplo:
$_SESSION['checkMe']
ou com quantos níveis de profundidade você precisar, por exemplo:
$clients['personal']['address']['postcode']


 

Supressão:

É possível suprimir o PHP Notices com @ou reduzir seu nível de relatório de erros, mas não corrige o problema , simplesmente impede que ele seja relatado no log de erros. Isso significa que seu código ainda tentou usar uma variável que não foi definida, o que pode ou não significar que algo não funciona conforme o esperado - dependendo da importância do valor ausente.

Você realmente deve verificar esse problema e resolvê-lo adequadamente, exibindo uma mensagem diferente ou apenas retornando um valor nulo para todo o resto para identificar o estado preciso.

Se você apenas se preocupa com o fato de o Aviso não estar no log de erros, como opção, você pode simplesmente ignorar o log de erros.

James
fonte
1

Uma causa comum de uma variável que não existe após o envio de um formulário HTML é o elemento do formulário que não está contido em uma <form>tag:

Exemplo: Elemento não contido dentro do <form>

<form action="example.php" method="post">
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>

<select name="choice">
    <option value="choice1">choice 1</option>
    <option value="choice2">choice 2</option>
    <option value="choice3">choice 3</option>
    <option value="choice4">choice 4</option>
</select>

Exemplo: Elemento agora contido no diretório <form>

<form action="example.php" method="post">
    <select name="choice">
        <option value="choice1">choice 1</option>
        <option value="choice2">choice 2</option>
        <option value="choice3">choice 3</option>
        <option value="choice4">choice 4</option>
    </select>
    <p>
        <input type="text" name="name" />
        <input type="submit" value="Submit" />
    </p>
</form>
John Conde
fonte
0

Provavelmente você estava usando a versão antiga do PHP até o momento e agora o PHP atualizado é a razão pela qual ele estava funcionando sem nenhum erro até agora de anos. até o PHP4 não havia erro se você estiver usando a variável sem defini-la, mas a partir do PHP5 em diante ele gera erros para códigos como os mencionados na pergunta.

phvish
fonte
0

Ao lidar com arquivos, são necessários um tipo de codificação adequado e um método POST, que acionará um aviso de índice indefinido se um deles não estiver incluído no formulário.

O manual declara a seguinte sintaxe básica:

HTML

<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE must precede the file input field -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- Name of input element determines name in $_FILES array -->
    Send this file: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

PHP

<?php
// In PHP versions earlier than 4.1.0, $HTTP_POST_FILES should be used instead
// of $_FILES.

$uploaddir = '/var/www/uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

?>

Referência:

Funk Quarenta Niner
fonte
0

Fiz uma pergunta sobre isso e fui encaminhado para este post com a mensagem:

Esta pergunta já tem uma resposta aqui:

“Aviso: variável indefinida”, “Aviso: índice indefinido” e “Aviso: deslocamento indefinido” usando PHP

Estou compartilhando minha pergunta e solução aqui:

Este é o erro:

insira a descrição da imagem aqui

A linha 154 é o problema. Isto é o que tenho na linha 154:

153    foreach($cities as $key => $city){
154        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){

Eu acho que o problema é que eu estou escrevendo, se as condições para a variável $city, que não é a chave, mas o valor $key => $city. Primeiro, você pode confirmar se essa é a causa do aviso? Segundo, se esse é o problema, por que não consigo escrever uma condição com base no valor? Tem que ser com a chave que eu preciso para escrever a condição?

ATUALIZAÇÃO 1: O problema é que, ao executar $citiesCounterArray[$key], às vezes $keycorresponde a uma chave que não existe na $citiesCounterArraymatriz, mas esse nem sempre é o caso com base nos dados do meu loop. O que eu preciso é definir uma condição para que, se $keyexistir na matriz, execute o código, caso contrário, ignore-o.

ATUALIZAÇÃO 2: Foi assim que eu o corrigi usando array_key_exists():

foreach($cities as $key => $city){
    if(array_key_exists($key, $citiesCounterArray)){
        if(($city != 'London') && ($city != 'Madrid') && ($citiesCounterArray[$key] >= 1)){
Jaime Montoya
fonte
0

Esses erros ocorrem sempre que estamos usando uma variável que não está definida.

A melhor maneira de lidar com isso é definir o relatório de erros durante o desenvolvimento.

Para definir o relatório de erros em:

ini_set('error_reporting', 'on');
ini_set('display_errors', 'on');
error_reporting(E_ALL);

Nos servidores de produção, o relatório de erros está desativado; portanto, não obtemos esses erros.

No servidor de desenvolvimento, no entanto, podemos definir o relatório de erros.

Para se livrar desse erro, vemos o seguinte exemplo:

if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

Podemos inicializar as variáveis NULLantes de atribuir seus valores ou usá-los.

Portanto, podemos modificar o código como:

$test = NULL;
if ($my == 9) {
 $test = 'yes';  // Will produce error as $my is not 9.
}
echo $test;

Isso não perturbará nenhuma lógica do programa e não produzirá aviso, mesmo $testque não tenha valor.

Então, basicamente, é sempre melhor ativar o relatório de erros para desenvolvimento.

E corrija todos os erros.

E na produção, o relatório de erros deve estar desativado.

da pupila
fonte
-1

Esses avisos são porque você não possui a variável usada definede a my_indexchave não estava presente na $my_arrayvariável.

Esses avisos eram acionados toda vez, porque seu code não está correto, mas provavelmente você não tinha o relatório de avisos .

Resolva os erros:

$my_variable_name = "Variable name"; // defining variable
echo "My variable value is: " . $my_variable_name;

if(isset($my_array["my_index"])){
    echo "My index value is: " . $my_array["my_index"]; // check if my_index is set 
}

Outra maneira de fazer isso:

ini_set("error_reporting", false)
Andrei Todorut
fonte
-2

No PHP, você precisa primeiro definir a variável depois que você pode usá-la.
Podemos verificar se a variável está definida ou não de maneira muito eficiente!

//If you only want to check variable has value and value has true and false value.
//But variable must be defined first.

if($my_variable_name){

}

//If you want to check variable is define or undefine
//Isset() does not check that variable has true or false value
//But it check null value of variable
if(isset($my_variable_name)){

}

Explicação Simples

//It will work with :- true,false,NULL
$defineVarialbe = false;
if($defineVarialbe){
    echo "true";
}else{
    echo "false";
}

//It will check variable is define or not and variable has null value.
if(isset($unDefineVarialbe)){
    echo "true";
}else{
    echo "false";
}
Manish Goswami
fonte