Я запускаю сценарий 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"];
В чем смысл этих сообщений об ошибках?
Почему они появляются внезапно? Я использовал этот скрипт годами, и у меня никогда не было проблем.
Как мне их починить?
Это общий справочный вопрос чтобы люди ссылались на них как на дубликаты, вместо того, чтобы объяснять проблему снова и снова. Я чувствую, что это необходимо, потому что большинство реальных ответов на этот вопрос очень специфичны.
Связанная мета-дискуссия:
Из огромной мудрости Руководство по 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
тот, который даже не сообщается по умолчанию, но Руководство советует разрешить во время разработки.
Способы решения проблемы:
Рекомендуемые: Объявите ваши переменные, например, когда вы пытаетесь добавить строку в неопределенную переменную. Или использовать 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'] ?? '';
Установить пользовательский обработчик ошибок для E_NOTICE и перенаправить сообщения из стандартного вывода (возможно, в файл журнала):
set_error_handler('myHandlerForMinorErrors', E_NOTICE | E_STRICT)
Отключить E_NOTICE от отчетов. Быстрый способ исключить просто E_NOTICE
является:
error_reporting( error_reporting() & ~E_NOTICE )
Подавить ошибку с помощью @ оператор.
Замечания: Настоятельно рекомендуется реализовать только пункт 1.
Это уведомление появляется, когда вы (или PHP) пытаетесь получить доступ к неопределенному индексу массива.
Способы решения проблемы:
Проверьте, существует ли индекс, прежде чем получить к нему доступ. Для этого вы можете использовать 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'] : '';
Языковая конструкция 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 переменные Суперглобальные и в верхнем регистре.
Связанные с:
Попробуйте это
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);
Примечание о сессиях:
При использовании сессий, session_start();
требуется размещать во всех файлах с использованием сессий.
@
операторДля нежелательных и избыточных уведомлений можно использовать выделенный @
оператор к »скрывать«Неопределенная переменная / индекс сообщения.
$var = @($_GET["optional_param"]);
isset?:
или же ??
супер супрессия однако. Уведомления все еще могут быть зарегистрированы. И можно воскресить @
скрытые уведомления с: set_error_handler("var_dump");
if (isset($_POST["shubmit"]))
в вашем исходном коде.@
или же isset
только после проверка работоспособности.Сначала устраните причину. Не уведомления.
@
в основном приемлемо для $_GET
/$_POST
входные параметры, в частности если они необязательны.И поскольку это покрывает большинство таких вопросов, давайте рассмотрим наиболее распространенные причины:
$_GET
/ $_POST
/ $_REQUEST
неопределенный вводПервое, что вы делаете при обнаружении неопределенного индекса / смещения, это проверка на опечатки:
$count = $_GET["whatnow?"];
Во-вторых, если уведомление не имеет явной причины, используйте 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 рядом.$_REQUEST['vars']
опять же, который смешивает параметры GET и POST.Если вы используете mod_rewrite, то вы должны проверить оба access.log
а также включить RewriteLog
выяснить отсутствующие параметры.
$_FILES
$_FILES["formname"]
,enctype=multipart/form-data
method=POST
в вашем <form>
декларация.$_COOKIE
$_COOKIE
массив никогда не заполняется сразу после setcookie()
, но только при любом последующем HTTP-запросе.Вообще из-за «плохого программирования» и возможности ошибок сейчас или позже.
if (isset($varname))
перед использованиемЭто означает, что вы тестируете, оцениваете или печатаете переменную, которой вы еще ничего не присвоили. Это означает, что у вас либо опечатка, либо вам нужно сначала проверить, что переменная была инициализирована. Проверьте ваши логические пути, это может быть установлено в одном пути, но не в другом.
Я не хотел отключать уведомление, потому что это полезно, но хотел избежать слишком большого количества печатания.
Мое решение было этой функцией:
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')?>
Лучший способ получить информацию строка является:
$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');
Это потому, что переменная ‘$ 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;