массивы — & quot; Уведомление: неопределенная переменная & quot ;, & quot; Уведомление: неопределенный индекс & quot; и & quot; Уведомление: неопределенное смещение & quot; использование переполнения стека

Я запускаю сценарий 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"];

В чем смысл этих сообщений об ошибках?

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

Как мне их починить?

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

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

1028

Решение

Из огромной мудрости Руководство по PHP:

Использование значения по умолчанию для неинициализированной переменной проблематично в случае включения одного файла в другой, который использует то же имя переменной. Это также основной риск безопасности с register_globals включенный. E_NOTICE Ошибка уровня выдается в случае работы с неинициализированными переменными, но не в случае добавления элементов в неинициализированный массив. Исеть () Языковая конструкция может использоваться для определения, была ли переменная уже инициализирована. Дополнительно и более идеальным является решение пустой () поскольку он не генерирует предупреждение или сообщение об ошибке, если переменная не инициализирована.

От PHP документация:

Предупреждение не генерируется, если переменная не существует. Это означает
пустой () по сути, краткий эквивалент !isset ($ var) || $ вар
== ложь
.

Это означает, что вы можете использовать только empty() определить, установлена ​​ли переменная, и, кроме того, она проверяет переменную по следующим параметрам: 0,"",null,

Пример:

$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";
});

Проверьте приведенный выше фрагмент в 3v4l.org онлайн редактор PHP

Хотя PHP не требует объявления переменных, он рекомендует его для того, чтобы избежать некоторых уязвимостей или ошибок, связанных с безопасностью, когда можно забыть присвоить значение переменной, которая будет использоваться позже в скрипте. В случае необъявленных переменных PHP делает ошибку очень низкого уровня, E_NOTICEтот, который даже не сообщается по умолчанию, но Руководство советует разрешить во время разработки.

Способы решения проблемы:

  1. Рекомендуемые: Объявите ваши переменные, например, когда вы пытаетесь добавить строку в неопределенную переменную. Или использовать isset() / !empty() проверить, объявлены ли они, прежде чем ссылаться на них, как в:

    //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'] : '';
    

    Начиная с PHP 7.0 это стало намного чище, теперь вы можете использовать нулевой оператор объединения:

    // Null coalesce operator - No need to explicitly initialize the variable.
    $value = $_POST['value'] ?? '';
    
  2. Установить пользовательский обработчик ошибок для E_NOTICE и перенаправить сообщения из стандартного вывода (возможно, в файл журнала):

    set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
    
  3. Отключить E_NOTICE от отчетов. Быстрый способ исключить просто E_NOTICE является:

    error_reporting( error_reporting() & ~E_NOTICE )
    
  4. Подавить ошибку с помощью @ оператор.

Замечания: Настоятельно рекомендуется реализовать только пункт 1.

Это уведомление появляется, когда вы (или PHP) пытаетесь получить доступ к неопределенному индексу массива.

Способы решения проблемы:

  1. Проверьте, существует ли индекс, прежде чем получить к нему доступ. Для этого вы можете использовать isset() или же 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. Языковая конструкция list() может генерировать это, когда он пытается получить доступ к индексу массива, который не существует:

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

Две переменные используются для доступа к двум элементам массива, однако есть только один элемент массива, индекс 0, так что это будет генерировать:

Примечание: неопределенное смещение: 1

Приведенные выше уведомления часто появляются при работе с $_POST, $_GET или же $_SESSION, За $_POST а также $_GET Вы просто должны проверить, существует ли индекс, прежде чем использовать их. За $_SESSION Вы должны убедиться, что сессия началась с session_start() и что индекс также существует.

Также обратите внимание, что все 3 переменные Суперглобальные и в верхнем регистре.

Связанные с:

+947

Другие решения

Попробуйте это

Q1: это уведомление означает, что $ varname не
определяется в текущем объеме
скрипт.

Q2: Использование условий isset (), empty () перед использованием любой подозрительной переменной работает хорошо.

// 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'];
}

Или как быстрое и грязное решение:

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

Примечание о сессиях:

120

Ошибка отображения @ оператор

Для нежелательных и избыточных уведомлений можно использовать выделенный @ оператор к »скрывать«Неопределенная переменная / индекс сообщения.

$var = @($_GET["optional_param"]);
  • Это обычно не рекомендуется. Новички склонны злоупотреблять этим.
  • Это очень неуместно для кода глубоко внутри логики приложения (игнорируя необъявленные переменные, где вы не должны), например для параметров функции или в циклах.
  • Есть один перевес над isset?: или же ?? супер супрессия однако. Уведомления все еще могут быть зарегистрированы. И можно воскресить @скрытые уведомления с: set_error_handler("var_dump");
    • Кроме того, вы не должны обычно использовать / рекомендовать if (isset($_POST["shubmit"])) в вашем исходном коде.
    • Новички не заметят такие опечатки. Это просто лишает вас уведомлений PHP для тех самых случаев. добавлять @ или же isset только после проверка работоспособности.
    • Сначала устраните причину. Не уведомления.

  • @ в основном приемлемо для $_GET/$_POST входные параметры, в частности если они необязательны.

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

$_GET / $_POST / $_REQUEST неопределенный ввод

  • Первое, что вы делаете при обнаружении неопределенного индекса / смещения, это проверка на опечатки:
    $count = $_GET["whatnow?"];

    • Это ожидаемое ключевое имя и присутствует на каждый запрос страницы?
    • Имена переменных а также индикаторы массива чувствительны к регистру в PHP.
  • Во-вторых, если уведомление не имеет явной причины, используйте var_dump или же print_r проверять все входные массивы для их текущего содержания:

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

    Оба покажут, был ли ваш скрипт вызван с правильными или какими-либо параметрами вообще.

  • В качестве альтернативы или дополнительно используйте ваш браузер devtools (F12) и проверьте вкладку сети для запросов и параметров:

    инструменты разработчика браузера / вкладка сети

    Параметры POST и вход GET будут показаны отдельно.

  • За $_GET Параметры, которые вы также можете посмотреть на QUERY_STRING в

    print_r($_SERVER);
    

    PHP имеет некоторые правила для сливаться нестандартные имена параметров в суперглобалах. Апач может также переписать.
    Вы также можете посмотреть на поставляемое сырье $_COOKIES и другие заголовки HTTP-запросов.

  • Более очевидно, посмотрите на адресную строку вашего браузера для ПОЛУЧИТЬ параметры:

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

    name=value пары после ? знак вопроса — это параметры вашего запроса (GET). Таким образом, этот URL может только дать $_GET["id"] а также $_GET["sort"],

  • Наконец проверьте свой <form> а также <input> объявления, если вы ожидаете параметр, но не получаете ничего.

    • Убедитесь, что каждый необходимый вход имеет <input name=FOO>
    • id= или же title= атрибута не хватает.
    • method=POST форма должна заселять $_POST,
    • Принимая во внимание, что method=GET (или опуская это) даст $_GET переменные.
    • Форма также может быть предоставлена action=script.php?get=param через $ _GET и оставшиеся method=POST поля в $ _POST рядом.
    • С современными конфигурациями PHP (≥ 5.6) он стал выполнимый (не модно) использовать $_REQUEST['vars'] опять же, который смешивает параметры GET и POST.
  • Если вы используете mod_rewrite, то вы должны проверить оба access.log а также включить RewriteLog выяснить отсутствующие параметры.

$_FILES

  • Те же проверки работоспособности применяются к загрузке файлов и $_FILES["formname"],
  • Кроме того, проверьте enctype=multipart/form-data
  • Так же как method=POST в вашем <form> декларация.
  • Смотрите также: PHP Неопределенная ошибка индекса $ _FILES?

$_COOKIE

  • $_COOKIE массив никогда не заполняется сразу после setcookie(), но только при любом последующем HTTP-запросе.
  • Кроме того, срок их действия истекает, они могут быть ограничены поддоменами или отдельными путями, и пользователь и браузер могут просто отклонить или удалить их.
55

Вообще из-за «плохого программирования» и возможности ошибок сейчас или позже.

  1. Если это ошибка, сначала сделайте правильное присвоение переменной: $ varname = 0;
  2. Если это действительно только иногда определяется, проверьте это: if (isset($varname))перед использованием
  3. Если это потому, что вы написали это неправильно, просто исправьте это
  4. Может быть, даже очередь предупреждений в вас PHP-настройка
41

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

38

Я не хотел отключать уведомление, потому что это полезно, но хотел избежать слишком большого количества печатания.

Мое решение было этой функцией:

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

Поэтому, если я хочу сослаться на $ name и echo, если существует, я просто пишу:

<?=ifexists('name')?>

Для элементов массива:

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

На странице, если я хочу сослаться на $ _REQUEST [‘name’]:

<?=ifexistsidx($_REQUEST,'name')?>
33

Лучший способ получить информацию строка является:

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

Этот однострочник почти эквивалентен:

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

Если вы абсолютно хотите строка значение, как:

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

Это потому, что переменная ‘$ user_location’ не определена. Если вы используете какой-либо цикл if, внутри которого вы объявляете переменную ‘$ user_location’, то вы также должны иметь цикл else и определять его. Например:

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

Приведенный выше код создаст ошибку, так как цикл if не выполнен, а в цикле else ‘$ user_location’ не определен. Тем не менее, PHP попросили отобразить переменную. Таким образом, чтобы изменить код, вы должны сделать следующее:

$a=10;
if($a==5) { $user_location='Paris';} else { $user_location='SOMETHING OR BLANK'; }
echo $user_location;
24
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector