«Примечание: неопределенная переменная», «Примечание: неопределенный индекс» и «Примечание: неопределенное смещение» с использованием PHP - PullRequest
1096 голосов
/ 24 ноября 2010

Я запускаю PHP-скрипт и продолжаю получать ошибки, такие как:

Примечание: неопределенная переменная: my_variable_name в C: \ wamp \ www \ mypath \ index.php в строке 10

Примечание: неопределенный индекс: my_index C: \ wamp \ www \ mypath \ index.php в строке 11

Строки 10 и 11 выглядят так:

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

Что означают эти сообщения об ошибках?

Почему они появляются внезапно?Я использовал этот сценарий годами, и у меня никогда не было проблем.

Как мне их исправить?

Это общий справочный вопрос , на который люди могут ссылаться как на дубликаты, вместо того, чтобы объяснять проблему снова и снова.Я чувствую, что это необходимо, потому что большинство реальных ответов на этот вопрос очень специфичны.

Связанная мета-дискуссия:

Ответы [ 28 ]

16 голосов
/ 28 июля 2015

Раньше я проклинал эту ошибку, но может быть полезно напомнить вам, что нужно избегать ввода пользователя.

Например, если вы подумали, что это был умный, сокращенный код:

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

... Подумай еще раз!Лучшее решение:

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

(я использую пользовательскую функцию html() для экранирования символов, ваш пробег может отличаться)

14 голосов
/ 18 декабря 2015

На очень Простом языке .Ошибка в том, что вы используете переменную $user_location, которая не была определена вами ранее и не имеет никакого значения. Поэтому я рекомендую вам объявить эту переменную до используя это, например:$user_location = ''; Или $user_location = 'Los Angles';Это очень распространенная ошибка, с которой вы можете столкнуться. Не беспокойтесь, просто объявите переменную и Наслаждайтесь кодированием .

14 голосов
/ 09 апреля 2013

Я все время использую собственную полезную функцию exst () , которая автоматически объявляет переменные.

Ваш код будет -

$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;
}
14 голосов
/ 13 декабря 2016

В PHP 7.0 теперь можно использовать оператор объединения нулей:

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

Равен:

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

PHP manual PHP 7.0

8 голосов
/ 29 ноября 2016

ПОЧЕМУ ЭТО ПРОИСХОДИТ?

Со временем PHP стал более ориентированным на безопасность языком. Настройки, которые раньше были отключены по умолчанию, теперь включены по умолчанию. Прекрасным примером этого является E_STRICT, который стал включенным по умолчанию с PHP 5.4.0 .

Кроме того, согласно документации PHP, по умолчанию, E_NOTICE отключен в php.ini. Документы PHP рекомендуют включить его для целей отладки . Однако, когда я загружаю PHP из репозитория Ubuntu - и из стека Windows BitNami - я вижу что-то еще.

; 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

Обратите внимание, что на самом деле error_reporting по умолчанию установлено на производственное значение, а не на значение по умолчанию. Это несколько сбивает с толку и не документировано за пределами php.ini, поэтому я не проверил это в других дистрибутивах.

Однако, чтобы ответить на ваш вопрос, эта ошибка появляется сейчас, когда она не появлялась раньше, потому что:

  1. Вы установили PHP, и новые настройки по умолчанию немного плохо документированы, но не исключают E_NOTICE.

  2. E_NOTICE предупреждения, такие как неопределенные переменные и неопределенные индексы, на самом деле помогают сделать ваш код чище и безопаснее. Я могу вам сказать, что несколько лет назад включение E_NOTICE заставило меня объявить мои переменные. Это значительно облегчило изучение языка C, если не объявлять переменные, это намного больше неприятностей.

Что я могу сделать об этом?

  1. Выключите E_NOTICE, скопировав «Значение по умолчанию» E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED и заменив его на то, что в данный момент не комментируется после знака равенства в error_reporting =. Перезапустите Apache или PHP, если используете CGI или FPM. Убедитесь, что вы редактируете «правильный» php.ini. Правильный вариант будет Apache, если вы используете PHP с Apache, fpm или php-fpm, если вы используете PHP-FPM, cgi, если вы используете PHP-CGI и т. Д. Это не рекомендуемый метод, но если у вас есть устаревший код, который собирается быть чрезвычайно трудным для редактирования, тогда это может быть вашей лучшей ставкой.

  2. Отключите E_NOTICE на уровне файлов или папок. Это может быть предпочтительнее, если у вас есть какой-то устаревший код, но в противном случае вы хотите сделать все «правильно». Для этого вам следует проконсультироваться с Apache2, Nginx или любым другим вашим сервером. В Apache вы должны использовать php_value внутри <Directory>.

  3. Перепишите свой код, чтобы он стал чище. Если вам нужно сделать это при переходе в производственную среду или вы не хотите, чтобы кто-то видел ваши ошибки, убедитесь, что вы отключили отображение ошибок и только регистрируете ваши ошибки (см. display_errors и log_errors в php.ini и настройках вашего сервера).

Чтобы расширить вариант 3: это идеальный вариант. Если вы можете пойти по этому пути, вы должны. Если вы изначально не идете по этому пути, рассмотрите возможность его перемещения в конечном итоге, протестировав свой код в среде разработки. Пока вы в этом, избавьтесь от ~E_STRICT и ~E_DEPRECATED, чтобы увидеть, что может пойти не так в будущем. Вы увидите много незнакомых ошибок, но это предотвратит возникновение неприятных проблем при необходимости обновления PHP в будущем.

ЧТО ОЗНАЧАЮТ ОШИБКИ?

Undefined variable: my_variable_name - это происходит, когда переменная не была определена перед использованием. Когда скрипт PHP выполняется, он просто принимает нулевое значение. Однако в каком сценарии вам нужно проверить переменную, прежде чем она будет определена? В конечном счете, это аргумент в пользу «небрежного кода». Как разработчик, я могу сказать, что мне нравится, когда я вижу проект с открытым исходным кодом, в котором переменные определены настолько высоко, насколько это возможно. Это упрощает определение переменных, которые появятся в будущем, и облегчает чтение / изучение кода.

function foo()
{
    $my_variable_name = '';

    //....

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

Undefined index: my_index - Это происходит, когда вы пытаетесь получить доступ к значению в массиве, а оно не существует. Чтобы предотвратить эту ошибку, выполните условную проверку.

// 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;   

Другой вариант - объявить пустой массив в верхней части вашей функции. Это не всегда возможно.

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

//...

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

(дополнительный совет)

  • Когда я столкнулся с этими и другими проблемами, я использовал NetBeans IDE (бесплатно), и он дал мне множество предупреждений и уведомлений,Некоторые из них предлагают очень полезные советы.Это не является обязательным требованием, и я больше не использую интегрированные среды разработки, за исключением крупных проектов.В наши дни я больше vim человек:).
8 голосов
/ 07 июня 2013

почему бы не сделать все просто?

<?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

?>
6 голосов
/ 27 января 2017

неопределенный индекс означает в массиве, который вы запросили для недоступного индекса массива, например

<?php 

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

?>

неопределенная переменная означает, что вы использовали полностью не существующую переменную или которая не определена или инициализирована этим именем, например

<?php print_r($myvar); ?>

неопределенное смещение означает, что в массиве вы запросили несуществующий ключ. И Решением для этого является проверка перед использованием

php> echo array_key_exists(1, $myarray);
4 голосов
/ 28 ноября 2016

Относительно этой части вопроса:

Почему они появляются внезапно? Я использовал этот сценарий годами, и у меня никогда не было проблем.

Определенных ответов нет, но вот некоторые возможные объяснения того, почему настройки могут «внезапно» измениться:

  1. Вы обновили PHP до более новой версии, которая может иметь другие значения по умолчанию для error_reporting, display_errors или других соответствующих настроек.

  2. Вы удалили или ввели некоторый код (возможно, в зависимости), который устанавливает соответствующие настройки во время выполнения, используя ini_set() или error_reporting() (найдите их в коде)

  3. Вы изменили конфигурацию веб-сервера (при условии, что здесь используется apache): .htaccess файлы и конфигурации vhost также могут управлять настройками php.

  4. Обычно уведомления не отображаются / не отображаются (см. Руководство по PHP ) поэтому возможно, что при настройке сервера файл php.ini не мог быть загружен по какой-то причине (права доступа к файлам ??), и вы использовали настройки по умолчанию. Позже «ошибка» была устранена (случайно), и теперь она МОЖЕТ загрузить правильный файл php.ini с установленным значением error_reporting для отображения уведомлений.

3 голосов
/ 24 июля 2017

Другая причина, по которой будет выдано неопределенное уведомление об индексе, заключается в том, что столбец был опущен в запросе к базе данных.

т.е:.

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

Затем пытаемся получить доступ к большему количеству столбцов / строк внутри цикла.

т.е:.

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

или в цикле 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

}

Что еще нужно отметить, это то, что в * NIX OS и Mac OS X все зависит от регистра.

Ознакомьтесь со следующими вопросами и ответами в стеке:

3 голосов
/ 18 мая 2017

Если вы работаете с классами, вы должны убедиться, что вы ссылаетесь на переменные-члены, используя $this:

class Person
{
    protected $firstName;
    protected $lastName;

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

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...