«Примечание: неопределенная переменная», «Примечание: неопределенный индекс» и «Примечание: неопределенное смещение» с использованием PHP

982

Я запускаю 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"];

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

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

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

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

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

  • 7
    Возможный дубликат ссылки. Что означает эта ошибка в PHP?
  • 0
    это просто уведомление, чтобы убедиться, что вы используете это правильно, и это не орфографическая ошибка или что-то ...
Показать ещё 10 комментариев
Теги:
arrays
variables
warnings
undefined-index

30 ответов

946
Лучший ответ

Примечание. Неопределенная переменная

Из обширной мудрости руководства PHP:

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

Из документации PHP:

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

Это означает, что вы можете использовать только 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 в случае необъявленных переменных, возникает ошибка очень низкого уровня, 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:

    // 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. Для $_POST и $_GET вам просто нужно проверить, существует ли индекс или нет, прежде чем использовать их. Для $_SESSION вам нужно убедиться, что сеанс запущен с session_start() и что индекс также существует.

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

Связанный:

  • 7
    @ dieselpower44 Несколько мыслей: у «оператора затвора» ( @ ) есть некоторые проблемы с производительностью. Кроме того, поскольку он подавляет все ошибки в определенной области, его использование без осторожности может маскировать сообщения, которые вы хотели бы видеть.
  • 6
    Сокрытие проблем НЕ является способом решения проблем. Элементы № 2 ... № 4 могут использоваться только на производственных серверах, но не в целом.
Показать ещё 8 комментариев
112

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

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

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

49

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

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

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

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

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

$_GET/$_POST/$_REQUEST undefined input

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

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

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

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

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

    Изображение 716

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

  • Для параметров $_GET вы также можете заглянуть в QUERY_STRING в

    print_r($_SERVER);
    

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

  • Более очевидно, посмотрите на адресную строку браузера для параметров GET:

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

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

$_COOKIE

  • Массив $_COOKIE никогда не заполняется сразу после setcookie(), но только по любому последующему HTTP-запросу.
  • Кроме того, срок их действия может быть ограниченным для субдоменов или отдельных путей, и пользователь и браузер могут просто отклонять или удалять их.
  • 2
    Если вам интересно, как это влияет на производительность, эта статья хорошо ее обобщает, derickrethans.nl/… .
  • 0
    @GajusKuizinas С 2009 года произошло несколько изменений, в частности php.net/ChangeLog-5.php#5.4.0 радикально изменил результат (см. «Оператор Zend Engine, производительность» и «Оператор молчания»).
Показать ещё 2 комментария
38

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

36

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

  1. Если это ошибка, сначала сделайте правильное назначение переменной: $ varname = 0;
  2. Если это действительно определено только иногда, протестируйте его: if (isset($varname)), прежде чем использовать его
  3. Если это из-за того, что вы неправильно это сделали, просто исправьте это
  4. Возможно даже поворот предупреждений в вас PHP-настройки
  • 4
    Пожалуйста, не выключайте предупреждения. В более строгих языках они часто означают «может быть ошибка, лучше проверить эту строку дважды» - на языке, столь же разрешающем, как PHP, они часто означают «этот код дерьмов и, вероятно, изобилует ошибками; я постараюсь сделать какой-то смысл, но лучше исправить это как можно скорее ".
  • 4
    Хотя я согласен с первыми тремя пунктами, № 4 просто ошибочен. Сокрытие проблемы не заставит ее исчезнуть, и это может даже вызвать больше проблем в будущем.
Показать ещё 2 комментария
32

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

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

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')?>
  • 2
    Ваша функция ifexists () не работает для меня в PHP 5.3. Переменные вызывающей стороны не доступны в локальной области действия функции (см. Область переменных ), если только они не являются суперглобальными или вы не используете $ GLOBALS , поэтому $foo = "BABAR"; ifexists('foo'); будет вообще возвращать ноль. (Курсив - это главы php.net.)
  • 0
    теперь вы получите "привет от" ... какой смысл? просто проверьте значение if( !empty($user) and !empty($location) ) echo "hello $user ..."
26

Лучший способ получить ввод строка:

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

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

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

Если вам абсолютно нужно значение string, как:

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

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

Для большинства сайтов очень часто работает под сообщением об ошибке "по умолчанию" "Показать все ошибки, но не" уведомления "и" устаревшие ". Это будет установлено в php.ini и применимо ко всем сайтам на сервере. Это означает, что эти" уведомления", используемые в примерах, будут подавлены (скрыты), тогда как другие ошибки, считающиеся более критичными, будут показаны/записаны.

Другим критическим параметром являются ошибки, которые могут быть скрыты (т.е. display_errors установлено значение "off" или "syslog" ).

Что произойдет в этом случае, так это то, что либо error_reporting был изменен, чтобы также показывать уведомления (в соответствии с примерами), и/или настройки были изменены на display_errors на экране (в отличие от их подавления/регистрации их).

Почему они изменились?

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

Однако также можно переопределить эти параметры в

  • .htconf(конфигурация веб-сервера, включая vhosts и подконфигурации) *
  • .htaccess
  • в самом php-коде

и любой из них также мог быть изменен.

Существует также добавленное осложнение, что конфигурация веб-сервера может включать/отключать директивы .htaccess, поэтому, если у вас есть директивы в .htaccess, которые внезапно начинают/прекращают работу, вам необходимо проверить это.

(.htconf/.htaccess предположим, что вы работаете как apache.Если запустить командную строку это не будет, если вы используете IIS или другой веб-сервер, тогда вам нужно будет проверить эти конфиги соответственно)

Резюме

  • Проверить error_reporting и display_errors директивы php в php.ini не изменились или что вы еще не используете другой php.ini.
  • Проверить error_reporting и display_errors директивы php в .htconf(или vhosts и т.д.) не изменились
  • Проверить error_reporting и display_errors директивы php в .htaccess не изменились
  • Если у вас есть директива в .htaccess, проверьте, разрешены ли они в файле .htconf.
  • Наконец, проверьте свой код; возможно, несвязанная библиотека; чтобы увидеть, установлены ли там error_reporting и display_errors директивы php.
23

Потому что переменная '$ 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;
17

Быстрое исправление заключается в том, чтобы назначить вашу переменную нулевым в верхней части кода

$user_location = null;
15

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

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

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

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

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

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

13

В очень Простой язык.
Ошибка заключается в том, что вы используете переменную $user_location, которая ранее не определена вами, и она не имеет никакого значения. Поэтому я рекомендую вам объявить эту переменную до с помощью, например:


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

Я использую всю полезную функцию времени 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;
}
12

В PHP 7.0 теперь можно использовать Null-коалесцирующий оператор:

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

Равенство:

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

PHP-руководство PHP 7.0

  • 1
    Ого, за этот ответ нужно больше голосовать сейчас, когда он доступен в PHP 7. Замечательное решение !!!
  • 0
    Это также хорошо работает в операторах if. if (is_array($my_array['idontexist'] ?? '')) { dosomething(); }
Показать ещё 1 комментарий
7

ПОЧЕМУ ЭТО ПРОИЗОШЛО?

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

Кроме того, согласно документации PHP, defualt, E_NOTICE отключен в php.ini. PHP docs рекомендует включить его для целей отладки. Однако, когда я загружаю 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, поэтому я не проверял это на других дистрибутивах.

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

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

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

ЧТО Я МОГУ СДЕЛАТЬ ОБ ЭТОМ?

  • Отключите 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 и т.д. Это не рекомендуемый метод, но если у вас есть устаревший код, который будет быть чрезвычайно сложным для редактирования, тогда это может быть вашим лучшим выбором.

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

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

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

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

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

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 (бесплатно), и он дал мне множество предупреждений и уведомлений. Некоторые из них предлагают очень полезные советы. Это не является обязательным требованием, и я больше не использую IDE, кроме крупных проектов. В наши дни я больше vim:).
7

почему бы не упростить вещи?

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

?>
5

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

<?php 

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

?>

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

<?php print_r($myvar); ?>

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

php> echo array_key_exists(1, $myarray);
3

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

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

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

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

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

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

  • Обычно уведомления не отображаются/отображаются (см. руководство по PHP) поэтому возможно, что при настройке сервера файл php.ini не может быть загружен по какой-либо причине (разрешения на файлы?), и вы были в настройках по умолчанию. Позже "ошибка" была решена (случайно), и теперь она может загрузить правильный файл php.ini с набором error_reporting, чтобы показывать уведомления.

2

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

то есть:.

$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 и Mac OS X все зависит от регистра.

Обратитесь к следующему Q & A on Stack:

  • 0
    Я должен задаться вопросом, почему это также было понижено.
2

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

class Person
{
    protected $firstName;
    protected $lastName;

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

        // Incorrect
        $lastName = $last;

        // Incorrect
        $this->$lastName = $last;
    }
}
1

Использование тернарности является простым, читаемым и чистым:

Предварительная PHP 7
Присвойте переменной значение другой переменной, если она установлена, иначе назначьте null (или другое значение по умолчанию, которое вам нужно):

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

PHP 7+
То же самое, за исключением использования Null Coalescing Operator. Вам больше не нужно вызывать isset() поскольку он встроен, и нет необходимости предоставлять возвращаемую переменную, поскольку предполагается, что она возвращает значение проверяемой переменной:

$newVariable = $thePotentialData ?? null;

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

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


Если вам не требуется устанавливать новую переменную, вы можете напрямую использовать тройное возвращаемое значение, например, с помощью echo, аргументов функции и т. Д.:

Эхо:

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

Функция:

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

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

Вышеуказанное будет работать одинаково с массивами, включая сеансы и т.д., Заменяя проверяемую переменную, например:
$_SESSION['checkMe']
или сколько бы ни было уровней глубины, например:
$clients['personal']['address']['postcode']


Подавление:

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

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

Если вам просто нужно, чтобы Уведомление не было в журнале ошибок, то в качестве опции вы могли просто проигнорировать журнал ошибок.

0

Я задал вопрос об этом, и я был отправлен на этот пост с сообщением:

На этот вопрос уже есть ответ:

"Примечание: неопределенная переменная", "Примечание: неопределенный индекс" и "Примечание: неопределенное смещение" с использованием PHP

Я делюсь своим вопросом и решением здесь:

Это ошибка:

Изображение 717

Проблема 154 - это проблема. Это то, что у меня есть в строке 154:

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

Я думаю, проблема в том, что я пишу, если условия для переменной $city, которая не является ключом, а значением в $key => $city. Во-первых, вы могли бы подтвердить, является ли это причиной предупреждения? Во-вторых, если это проблема, почему я не могу написать условие, основанное на значении? Должно ли это быть с ключом, который мне нужно написать условие?

ОБНОВЛЕНИЕ 1: Проблема в том, что при выполнении $citiesCounterArray[$key] иногда $key соответствует ключу, который не существует в массиве $citiesCounterArray, но это не всегда происходит на основе данных моего цикла. Мне нужно установить условие, чтобы, если в массиве существует $key, тогда запустите код, иначе пропустите его.

ОБНОВЛЕНИЕ 2: Я установил это с помощью array_key_exists():

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

Одна общая причина переменной, не существующей после HTML-формы, была представлена, поскольку элемент формы не содержится в <form>:

Пример: Элемент, не содержащийся в <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>

Пример: Элемент, который теперь содержится в <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>
0

если вы хотите остановить некоторое уведомление, используйте переменную @выше, например

@$abc

выше метод не является хорошим, но решение проблемы.

Используйте isset like:

if(isset($abc)){

}  
0

При работе с файлами требуется надлежащий enctype и POST-метод, который вызывает уведомление индекса undefined, если они не включены в форму.

В руководстве описывается следующий базовый синтаксис:

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

?>

Ссылка:

0

Вероятно, вы использовали старую версию PHP до и теперь обновили PHP, поэтому причина, по которой она работала без ошибок до сих пор с годами. пока PHP4 не будет ошибки, если вы используете переменную без ее определения, но начиная с PHP5 она выдает ошибки для таких кодов, как упомянуто в вопросе.

-1

Эти уведомления могут, потому что вы не использованную переменная defined и my_index ключ не присутствовал в $my_array переменной.

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

Решите ошибки:

$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 
}

Другой способ получить это:

ini_set("error_reporting", false)
-2

В PHP вам нужен кулак, чтобы определить переменную, после которой вы можете ее использовать.
Мы можем проверить, что переменная определена или нет очень эффективным способом !.

//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)){

}

Простое объяснение

//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";
}
-3

когда вы создаете переменную внутри класса, вам нужно поместить 'var' перед переменной, как показано ниже:

 class Person {
 var $yourname = "MIKE";
function say_hello(){
    echo "hello from inside a class".get_class($this);
    echo "<br/>";
}

}

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

echo "My variable value is: " . (isset($my_variable_name) && !empty($my_variable_name)) ? $my_variable_name : '';
echo "My index value is: " . (isset($my_array["my_index"]) && !empty($my_array["my_index"])) ? $my_array["my_index"] : '';

Ещё вопросы

Сообщество Overcoder
Наверх
Меню