Ошибка в php: Warning: Undefined array key "chatWindow_enterAndSend_toUser" in ...\mainph.php on line 7

Есть код в файле index.php:

<form id="chatWindow_enterAndSend" action="index.php" method="POST">
          <input type="text" name="chatWindow_enterAndSend_input" autocomplete="off" placeholder="Enter message..." id="writeMessageField">
          <button type="submit" name="sendButtonName" id="sendButton" class="btn"> <img src="src/sendmess.png" alt="send" id="sendButton_img"> </button>
          <input type="text" name="chatWindow_enterAndSend_toUser" autocomplete="off" readonly class="dontDisplay" id="toUserMessageSend">
</form>

И код в файле mainph.php, который призван обрабатывать последнее поле:

$mysql = new mysqli("...", "...", "...", "...");
session_start();
if (isset($_SESSION["login"]) && $_SESSION["login"] != "") {
  $REALUSERLOGIN = $_SESSION["login"];
  $REALUSERTARGET = $_POST["chatWindow_enterAndSend_toUser"];
}

if (isset($_POST['sendButtonName'])) {
  /* send messages code */
  $messageSendPost = $_POST["chatWindow_enterAndSend_input"];
  if ($messageSendPost != "" && isset($_SESSION["login"]) && $REALUSERTARGET != "") {
    $mysql->query("INSERT INTO messages (`fromUser`, `forUser`, `messageText`, `time`) VALUES ('$REALUSERLOGIN', '$REALUSERTARGET', '$messageSendPost', '20:33')");

    header("Location: /index.php");
    exit;
  }
}

Файлы между собой прекрасно взаимодействуют (там ещё куча кода, который работает). Раньше это поле мне было нужно только чтобы отправлять из него данные в базу данных (тогда с него считываются данные и отправляются в БД без каких-либо проблем. Это меня больше всего смущает, потому что переменная для этих случаев одна и имеет одно и то же значение), но сейчас появилась необходимость в коде проверять пустое ли это поле, а оно якобы не существует. Ещё раз напишу: даже когда в поле есть значения (иногда оно бывает пустым, тогда должно давать значение ""), php выдает предупреждение

(Warning: Undefined array key "chatWindow_enterAndSend_toUser" in ...\mainph.php on line 7)

и при этом без проблем в эту же секунду отправляет данные из этого поля в БД. Прошу не предлагать написать "@" перед _POST. Это я знаю, но мне это поле край-конец нужно для проверки в коде. Решение по типу '... ?? ""' мне тоже не подходит: всегда возвращается пустая строка, тк поля якобы нет. Дополнил второй код. Теперь буквально видно, что переменная одна и та же, данные в БД код отправляет (send messages code), в том числе и эту переменную, но при проверке её значения из кода выдаёт предупреждение выше. Для проверки в коде в другом месте используется идентичная строка:

if(... && $REALUSERTARGET != "") {
 /* mycode */
}

Но эту проверку он уже не проходит. Я не вижу в этом логики. Буду рад предоставить любую доп информацию


Ответы (2 шт):

Автор решения: Ипатьев

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

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

В данном случае очевидно, что первое обращение к $_POST["chatWindow_enterAndSend_toUser"] происходит ДО проверки, была ли отправлена форма. Соответственно, при прямом обращении к этому файлу (или при отправке другой формы) всегда будет выдаваться эта ошибка. И для решения этой "проблемы" надо всего лишь перенести инициализацию переменной $REALUSERTARGET туда, где она имеет смысл - внутрь условия, проверяющего отправку формы.

→ Ссылка
Автор решения: Solt

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

И немного разверну комментарий Ипатьева. Если за рамками блока не предполагается никаких действий, будет и читабельней без лишних вложений, и оптимальней в части выполнения:

if(!isset($_SESSION["login"]) || $_SESSION["login"] == "") {
  exit; //Или какой-то ответ об ошибке
}
$REALUSERLOGIN = $_SESSION["login"];

итд. Старайтесь логику программы держать в таком русле и она не превратится в бесконечную "лесенку", как это часто бывает, например, в js.

А обращение к $_POST всё-таки лучше задвинуть в проверку поста

if (isset($_POST['sendButtonName'])) {
    $REALUSERTARGET = $_POST["chatWindow_enterAndSend_toUser"];

Кроме того, никогда не подставляйте "сырые" данные в запросы. При SQL-инъекциях это может закончиться довольно плачевно. Примите за правило подготавливать запрос отдельно от подстановок и привязывать к нему переменные:

$stmt = $mysql->prepare("
  INSERT INTO messages (`fromUser`, `forUser`, `messageText`, `time`) 
  VALUES (?,?,?,?)");

$stmt->bind_param('ssss', $REALUSERLOGIN, $REALUSERTARGET, $messageSendPost,'20:33');
$stmt->execute();
→ Ссылка