php - notice - undefined variable row in




"Aviso: variável indefinida", "Aviso: índice indefinido" e "Aviso: compensação indefinida" usando PHP (19)

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 register_globals ativado. Erro de nível E_NOTICE é emitido no caso de trabalhar com variáveis ​​não inicializadas, mas não no caso de acrescentar elementos ao array não inicializado. isset() construção da linguagem isset() pode ser usada para detectar se uma variável já foi inicializada. Adicionalmente e mais ideal é a solução de empty() já que não gera uma mensagem de aviso ou erro se a variável não for inicializada.

Da empty() :

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

Isso significa que você pode usar apenas empty() para determinar se a variável está configurada e, além disso, verifica a variável com o seguinte, 0,"",null .

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 on-line do 3v4l.org

Embora o PHP não exija uma declaração de variáveis, recomenda-o a fim de evitar algumas vulnerabilidades de segurança ou erros nos quais alguém poderia esquecer de dar 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 é emitir um erro de nível muito baixo, E_NOTICE , um que nem sequer é reportado por padrão, mas o Manual aconselha a permitir durante o desenvolvimento.

Formas de lidar com o problema:

  1. Recomendado: declare suas variáveis, por exemplo, quando você tentar acrescentar uma string a uma variável indefinida. Ou use isset() / empty() para verificar se eles são declarados antes de referenciá-los, 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 se tornou muito mais limpo a partir do PHP 7.0, agora você pode usar o operador coalesce nulo :

    // 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. Desativar E_NOTICE do relatório. Uma maneira rápida de excluir apenas o 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 / offset indefinido

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

Formas 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 list() construções de linguagem list() pode gerar isso quando tentar 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, há apenas um elemento da matriz, índice 0 , portanto, isso gerará:

Aviso: indefinido deslocamento: 1

Variável $_POST / $_GET / $_SESSION

Os avisos acima aparecem frequentemente quando se trabalha com $_POST , $_GET ou $_SESSION . Para $_POST e $_GET você só precisa verificar se o índice existe ou não antes de usá-los. Para $_SESSION você tem que ter certeza de que a sessão iniciou com session_start() e que o índice também existe.

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

Relacionado:

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

A linha 10 e 11 se parece com isso:

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 usei esse script por anos e nunca tive nenhum problema.

Como faço para corrigi-los?

Esta é uma questão de referência geral para as pessoas vincularem como duplicadas, em vez de ter que explicar o problema repetidas vezes. Eu sinto que isso é necessário porque a maioria das respostas do mundo real sobre essa questão é muito específica.

Discussão meta relacionada:


Erro exibir operador @

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

$var = @($_GET["optional_param"]);
  • Isso geralmente é desencorajado. Os recém-chegados tendem a superutilizá-lo.
  • É muito inadequado para o 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 vantagem sobre o isset?: ou ?? super-supressão no entanto. Avisos ainda podem ser registrados. E pode-se ressuscitar os avisos @ set_error_handler("var_dump"); com: set_error_handler("var_dump");
    • Além disso, você não deve usar habitualmente / recommend if (isset($_POST["shubmit"])) em seu código inicial.
    • Os recém-chegados não vão identificar esses erros. Ele apenas priva você dos avisos do PHP para esses casos. Adicione @ ou isset somente após verificar a funcionalidade.
    • Corrija a causa primeiro. Não os avisos.

  • @ é principalmente aceitável para os parâmetros de entrada $_GET / $_POST , especificamente se forem opcionais .

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

$_GET / $_POST / $_REQUEST entrada indefinida

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

    • Este é um nome de chave esperado e está presente em cada solicitação de página?
    • Nomes de variáveis e índices de array são sensíveis a maiúsculas e minúsculas no PHP.
  • Em segundo lugar, se o aviso não tiver uma causa óbvia, use var_dump ou print_r para verificar todas as matrizes de entrada para seu conteúdo atual:

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

    Ambos irão revelar se o seu script foi invocado com o direito ou quaisquer parâmetros.

  • Alternativamente ou adicionalmente, use o seu devtools do navegador ( F12 ) e inspecione a guia de rede para solicitações e parâmetros:

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

  • Para os parâmetros $_GET você também pode espiar QUERY_STRING no

    print_r($_SERVER);

    O PHP tem algumas regras para coalesce nomes de parâmetros não padrão nas superglobais. O Apache também pode fazer algumas reescritas. Você também pode consultar os $_COOKIES e outros cabeçalhos de solicitação HTTP fornecidos dessa forma.

  • Mais obviamente, olhe para a barra de endereços do seu navegador para os parâmetros GET :

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

    O name=value pares de name=value após o ? ponto de interrogação são seus parâmetros de consulta (GET). Assim, essa URL poderia gerar apenas $_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.

    • Assegure-se de que cada entrada requerida tenha um <input name=FOO>
    • O atributo id= ou title= não é suficiente.
    • Um method=POST formulário deve preencher $_POST .
    • Considerando que um method=GET (ou deixando de fora) produziria variáveis $_GET .
    • Também é possível que um formulário forneça action=script.php?get=param por meio de $ _GET e o method=POST restante method=POST campos method=POST em $ _POST ao lado.
    • Com configurações modernas de PHP (≥ 5.6), tornou-se feasible (não elegante) usar $_REQUEST['vars'] novamente, o que faz com que os parâmetros GET e POST parem.
  • Se você está empregando o mod_rewrite, então deve checar tanto o access.log quanto habilitar o RewriteLog a descobrir os parâmetros ausentes.

$_FILES

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

$_COOKIE

  • A matriz $_COOKIE nunca é preenchida logo após setcookie() , mas apenas em qualquer solicitação HTTP de acompanhamento.
  • Além disso, sua validade expira, eles podem ser restritos a subdomínios ou caminhos individuais, e o usuário e o navegador podem apenas rejeitá-los ou excluí-los.

É porque a variável '$ user_location' não está sendo definida. Se você estiver usando algum loop if dentro do qual você está declarando a variável '$ user_location', então você também deve 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, pois o loop if não está satisfeito e no loop else '$ user_location' não foi definido. Ainda PHP foi solicitado a repetir a variável. Então, 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;

A melhor maneira de obter uma string de entrada é:

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

Este one-liner é quase equivalente a:

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

Se você quiser absolutamente valor de string , assim como:

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

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

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

// 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 função html() personalizada para escapar de caracteres, sua milhagem pode variar)


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

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

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

Então, se eu quiser referenciar $ name e echo, se existir, eu simplesmente escrevo:

<?=ifexists('name')?>

Para elementos de 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')?>

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

  1. Se for um erro, faça primeiro uma atribuição apropriada para a variável: $ varname = 0;
  2. Se realmente for definido apenas algumas vezes, teste: if (isset($varname)) , antes de usá-lo
  3. Se é porque você escreveu errado, apenas corrija isso
  4. Talvez até mesmo virar os avisos em você configurações PHP

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


Outra razão pela qual um aviso de índice indefinido será lançado, seria que uma coluna foi omitida de uma consulta de 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 loop while:

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 fazem distinção entre maiúsculas e minúsculas.

Consulte as seguintes perguntas e respostas na pilha:


Se estiver trabalhando com classes, você precisa se certificar de fazer referência a 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;
    }
}

Tente esse

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

Q2: 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 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:


Usar um ternary é simples, legível e limpo:

Pré PHP 7
Atribua uma variável ao valor de outra variável se ela estiver configurada, senão atribua null (ou qualquer valor padrão que você precise):

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

PHP 7+
O mesmo, exceto usando o Operador Coalescente Nulo . Não há mais a necessidade de chamar isset() pois isso é construído, e não há necessidade de fornecer a variável para retornar, pois é assumido que retorna o valor da variável que está sendo verificada:

$newVariable = $thePotentialData ?? null;

Ambos irão parar os Avisos da questão do OP, e ambos são o equivalente exato de:

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


Se você não precisar configurar uma nova variável, poderá usar diretamente o valor retornado do ternário, como, por exemplo 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
    }
}

Os itens acima funcionarão da mesma forma com arrays, incluindo sessões etc, substituindo a variável que está sendo verificada com, por exemplo:
$_SESSION['checkMe']
ou quantos níveis de profundidade forem necessários, por exemplo:
$clients['personal']['address']['postcode']

Supressão:

É possível suprimir os Avisos PHP com @ou reduzir seu nível de relatório de erros, mas isso não corrige o problema , ele 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 como esperado - dependendo de quão crucial é o valor ausente.

Você realmente deve verificar esse problema e manipulá-lo adequadamente, seja servindo uma mensagem diferente ou até mesmo retornando um valor nulo para todo o resto para identificar o estado preciso.

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


o índice indefinido significa em uma matriz que você solicitou para 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 completamente variável não existente ou que não está definida ou inicializada por esse nome, por exemplo

<?php print_r($myvar); ?>

offset indefinido significa na matriz que você solicitou a chave não existente. E a solução para isso é verificar antes de usar

php> echo array_key_exists(1, $myarray);

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

?>

Tipo diferente de erros

1) Aviso: Variável indefinida

Você receberá este erro se não tiver definido a variável e estiver tentando acessar ou usar essa variável.

Exemplo:

    <?php
         echo $a;
     ?>

Notice: Undefined variable: a

2) Aviso: Índice indefinido e offset indefinido

Isso significa que você está se referindo a uma chave de matriz que não existe. "Offset"

refere-se à chave inteira de uma matriz numérica, e "index" refere-se à

string chave de um array associativo.

<?php 
$testArr=array("Test1", "Test2");

print $testArr[2]; //undefined offset

$myArr=array("val1"=>"1", "val2"=>"2");

print $myArr['val3']; //undefined index
?>

Ao lidar com arquivos, um enctype adequado e um método POST são necessários, o que acionará um aviso de índice indefinido se não estiverem incluídos no formulário.

O manual indica 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:


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

Esses avisos foram acionados todas as vezes, porque você codenão está correto, mas provavelmente você não tem o relatório de avisos.

Resolva os bugs:

$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 conseguir isso:

ini_set("error_reporting", false)

No PHP você precisa de punho para definir a variável depois que você pode usá-lo.
Podemos verificar a variável é 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";
}

Uma causa comum de uma variável que não existe depois que um formulário HTML é enviado é que o elemento de formulário 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 dentro do <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>




undefined-index