Co oznacza komunikat o błędzie PHP „Uwaga: użycie niezdefiniowanej stałej”?

163

PHP zapisuje ten błąd w logach: "Uwaga: użycie niezdefiniowanej stałej".

Błąd w logach:

PHP Notice:  Use of undefined constant department - assumed 'department' (line 5)
PHP Notice:  Use of undefined constant name - assumed 'name' (line 6)
PHP Notice:  Use of undefined constant email - assumed 'email' (line 7)
PHP Notice:  Use of undefined constant message - assumed 'message' (line 8)

Odpowiednie wiersze kodu:

$department = mysql_real_escape_string($_POST[department]);
$name = mysql_real_escape_string($_POST[name]);
$email = mysql_real_escape_string($_POST[email]);
$message = mysql_real_escape_string($_POST[message]);

Co to znaczy i dlaczego to widzę?

Nik
źródło

Odpowiedzi:

217

Powinieneś cytować swoje klucze tablicy:

$department = mysql_real_escape_string($_POST['department']);
$name = mysql_real_escape_string($_POST['name']);
$email = mysql_real_escape_string($_POST['email']);
$message = mysql_real_escape_string($_POST['message']);

Jak jest, to szukał stałych zwanych department, name, email, message, itd. Gdy nie znajdzie takiej stałej, PHP (dziwnie) interpretuje ją jako ciąg ( „dział”, etc). Oczywiście może to łatwo się zepsuć, jeśli później zdefiniujesz taką stałą (chociaż używanie małych małych liter jest złym stylem).

Matthew Flaschen
źródło
Czy odnosi się do zmiennej $ _POST?
Nik
3
@Przełęcz. Shrapnel, kiedy powiedziałem, że należy cytować tylko klucze tablicowe? Musi zacytować klucze, ale nie tylko.
Matthew Flaschen
1
dobrze mam na myśli, że nie ma potrzeby cytowania kluczy tablicowych . należy cytować ciągi znaków, a nie klucze tablicowe. klucz nie wymaga specjalnego cytowania.
Your Common Sense
4
To nie jest „dziwaczne”… Jest „kompatybilne wstecz”. PHP początkowo dopuszczało, a nawet promowało używanie niecytowanych ciągów znaków jako kluczy. (Okej, może wciąż jest "dziwaczne". :-)
Brian White
1
@BrianWhite Zabawny fakt, proponując wycofanie tej funkcji , nie mogłem znaleźć żadnych dowodów na to, że kiedykolwiek była ona oficjalnie zalecana, a tylko wersje beta PHP 3.0 zawierały zachowanie bez powiadomienia, więc wydaje się być wstecznie kompatybilny z funkcją, która była nigdy nie wydany. W każdym razie w PHP 8.0 zniknie, gdy tylko się pojawi.
IMSoP
77

Komunikat o błędzie jest spowodowany niefortunnym faktem, że PHP niejawnie zadeklaruje nieznany token jako stały ciąg o tej samej nazwie.

Oznacza to, że próbuje to zinterpretować (zwróć uwagę na brakujące cudzysłowy):

$_POST[department]

Jedynym prawidłowym sposobem, w jaki byłaby to poprawna składnia w PHP, jest sytuacja, gdy wcześniej departmentzdefiniowano stałą . Tak więc niestety, zamiast umierać z powodu błędu krytycznego w tym momencie, wydaje to powiadomienie i działa tak, jakby stała została zdefiniowana o tej samej nazwie i wartości:

// Implicit declaration of constant called department with value 'department'
define('department', 'department');  

Ten komunikat o błędzie można uzyskać na różne sposoby, ale wszystkie mają tę samą główną przyczynę - token, który może być stałą.

Brakujące cudzysłowy: $my_array[bad_key]

Na tym polega problem w twoim przypadku, a to dlatego, że masz klucze tablicy ciągów, które nie są cytowane. Naprawienie klawiszy ciągów naprawi błąd:

Zmiana:

$department = mysql_real_escape_string($_POST[department]);
...(etc)...

Do:

$department = mysql_real_escape_string($_POST['department']);
...(etc)...

Zmienny brakujący znak dolara: var_without_dollar

Innym powodem, dla którego możesz zobaczyć ten komunikat o błędzie, jest opuszczenie $zmiennej lub $this->członka. Np. Jedno z poniższych spowodowałoby podobny komunikat o błędzie:

my_local;   // should be $my_local
my_member;  // should be $this->my_member

Nieprawidłowy znak w nazwie zmiennej: $bad-variable-name

Podobny, ale bardziej subtelny problem może wystąpić, jeśli spróbujesz użyć niedozwolonego znaku w nazwie zmiennej - typowym przypadkiem byłby myślnik ( -) zamiast podkreślenia _.

Na przykład jest to OK, ponieważ podkreślenia są dozwolone w nazwach zmiennych :

if (123 === $my_var) {
  do_something();
}

Ale to nie jest:

if (123 === $my-var) {
  do_something();
}

Będzie to interpretowane tak samo, jak to:

if (123 === $my - var) {  // variable $my minus constant 'var'
  do_something();
}

Odwołanie się do stałej klasy bez określania zakresu klasy

Aby odwołać się do stałej klasy, musisz określić zakres klasy za pomocą ::, jeśli przegapisz tę wartość, PHP pomyśli, że mówisz o globalnej define().

Na przykład:

class MyClass {
  const MY_CONST = 123;

  public function my_method() {
    return self::MY_CONST;  // This is fine
  }


  public function my_method() {
    return MyClass::MY_CONST;  // This is fine
  }

  public function my_bad_method() {
    return MY_CONST;  // BUG - need to specify class scope
  }
}

Używanie stałej, która nie jest zdefiniowana w tej wersji PHP lub jest zdefiniowana w rozszerzeniu, które nie jest zainstalowane

Istnieje kilka stałych zdefiniowanych w systemie, które istnieją tylko w nowszych wersjach PHP, na przykład stałe opcji trybu dla, round()takie jak PHP_ROUND_HALF_DOWNistnieją tylko w PHP 5.3 lub nowszym.

Więc jeśli próbowałeś użyć tej funkcji w PHP 5.2, powiedz:

$rounded = round($my_var, 0, PHP_ROUND_HALF_DOWN);

Otrzymasz ten komunikat o błędzie:

Użycie niezdefiniowanej stałej PHP_ROUND_HALF_DOWN - przyjęto 'PHP_ROUND_HALF_DOWN' Ostrzeżenie (2): Niewłaściwa liczba parametrów dla rundy ()

John Carter
źródło
Dziękuję za udostępnienie. Brakowało mi tej self::części. Już działa.
moreirapontocom
Bez wątpienia ta odpowiedź jest bardziej wyczerpująca niż inne i zasługuje na odznakę najlepszej odpowiedzi! Za bardzo tęskniłem za zakresem zajęć i ostatecznie otrzymałem cenne informacje na przyszłość. Dzięki, John!
Harish ST
6

prawdopodobnie zapomniałeś użyć "".

Na przykład:

$_array[text] = $_var;

zmień na:

$_array["text"] = $_var;
Giancarlo
źródło
3

Brakowało Ci umieszczania pojedynczych cudzysłowów wokół kluczy tablicy:

$ _POST [e-mail]

Powinien być:

$ _POST ['email']

Ahmed Al-hajri
źródło
Powinien to być $ _POST ['email'];
Ibnul Quayum
1

Prawidłowy sposób używania zmiennych post to

<?php

$department = $_POST['department'];

?>

Użyj pojedynczego cudzysłowu (')

Srihari Goud
źródło
1
<?php 
  ${test}="test information";
  echo $test;
?>

Uwaga: Użycie niezdefiniowanego stałego testu - założono „test” w D: \ xampp \ htdocs \ sp \ test \ envoirnmentVariables.php w informacji o teście w wierszu 3

santoshvijaypawar
źródło
1

Wstaw pojedyncze cudzysłowy.

Przykład

$department = mysql_real_escape_string($_POST['department']);
$name = mysql_real_escape_string($_POST['name']);
$email = mysql_real_escape_string($_POST['email']);
$message = mysql_real_escape_string($_POST['message']); 
Hackbal Teamz
źródło
0

Nie jestem pewien, czy jest jakaś różnica. Używam kodu zapłonnika i używam "" dla nazw i działa świetnie.

$department = mysql_real_escape_string($_POST["department"]);
$name = mysql_real_escape_string($_POST["name"]);
$email = mysql_real_escape_string($_POST["email"]);
$message = mysql_real_escape_string($_POST["message"]);

pozdrowienia,

Jorge.

Jorge Vicente Mendoza
źródło
1
W tym przypadku nie ma różnicy między pojedynczymi i podwójnymi cudzysłowami.
Robbie Averill
1
@RobbieAverill, podczas gdy w tym przypadku w rzeczywistości nie ma - ponieważ ciągi znaków w pojedynczych cudzysłowach wyświetlają rzeczy tak, jak są, w których ciągi znaków podwójnego cudzysłowu analizują znaki ucieczki i oceniają zmienne, w tym scenariuszu dobrze jest używać ciągów w apostrofach.
Frankie
0

Wygląda na to, że predefiniowane stałe pobierania zniknęły wraz z rozszerzeniem MySQL, więc musimy je dodać przed pierwszą funkcją ...

// predefiniowane stałe pobierania

define('MYSQL_BOTH',MYSQLI_BOTH);
define('MYSQL_NUM',MYSQLI_NUM);
define('MYSQL_ASSOC',MYSQLI_ASSOC);

Przetestowałem i odniosłem sukces.

Venkat
źródło