Ich führe ein PHP-Skript aus, erhalte jedoch st?ndig eine Fehlermeldung wie diese:
Hinweis: Undefinierte Variable: my_variable_name in C:wampwwwmypathindex.php in Zeile 10
Hinweis: Undefinierter Index: my_index C:wampwwwmypathindex.php in Zeile 11
Warnung: Undefinierter Array-Schlüssel ?my_index“ in C:wampwwwmypathindex.php in Zeile 11
Die Zeilen 10 und 11 sehen so aus:
echo "My variable value is: " . $my_variable_name; echo "My index value is: " . $my_array["my_index"];
Was bedeuten diese Fehlermeldungen?
Warum erscheinen sie pl?tzlich? Ich benutze dieses Skript seit mehreren Jahren und hatte noch nie Probleme.
Wie behebe ich diese Fehler?
試一下這個(gè)
// 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']; }
或者,有一個(gè)快速而簡(jiǎn)單的解決方案:
// not the best solution, but works // in your php setting use, it helps hiding site wide notices error_reporting(E_ALL ^ E_NOTICE);
這個(gè)錯(cuò)誤信息旨在幫助PHP程序員在訪問(wèn)不存在的變量(或數(shù)組元素)時(shí)發(fā)現(xiàn)拼寫(xiě)錯(cuò)誤或錯(cuò)誤。因此,一個(gè)優(yōu)秀的程序員應(yīng)該:
盡管PHP不要求變量聲明,但建議進(jìn)行聲明,以避免一些安全漏洞或錯(cuò)誤,其中一個(gè)人可能會(huì)忘記給一個(gè)變量賦值,而這個(gè)變量稍后會(huì)在腳本中使用。在未聲明變量的情況下,PHP會(huì)發(fā)出一個(gè)E_WARNING級(jí)別的錯(cuò)誤。
此警告幫助程序員發(fā)現(xiàn)拼寫(xiě)錯(cuò)誤的變量名或類(lèi)似的錯(cuò)誤(例如,在條件求值為false時(shí)將變量賦值)。此外,未初始化變量可能存在其他可能的問(wèn)題。正如PHP手冊(cè)中所述,
這意味著變量可能從包含的文件中獲取一個(gè)值,并且這個(gè)值將被用來(lái)替代訪問(wèn)未初始化變量時(shí)所期望的null值,這可能導(dǎo)致不可預(yù)測(cè)的結(jié)果。為了避免這種情況,最好在使用之前對(duì)PHP文件中的所有變量進(jìn)行初始化。
處理這個(gè)問(wèn)題的方法有以下幾種:
推薦的方法是在使用之前聲明每個(gè)變量。這樣,只有在實(shí)際犯錯(cuò)嘗試使用不存在的變量時(shí),才會(huì)看到這個(gè)錯(cuò)誤,這也是出現(xiàn)這個(gè)錯(cuò)誤信息的原因。
//Initializing a variable $value = ""; //Initialization value; 0 for int, [] for array, etc. echo $value; // no error echo $vaule; // an error pinpoints a misspelled variable name
一個(gè)特殊情況是當(dāng)一個(gè)變量被定義但在函數(shù)中不可見(jiàn)。在PHP中,函數(shù)有自己的變量作用域,如果你需要在函數(shù)中使用外部的變量,它的值必須作為函數(shù)的參數(shù)傳遞進(jìn)來(lái):
function test($param) { return $param + 1; } $var = 0; echo test($var); // now $var's value is accessible inside through $param
使用空值合并運(yùn)算符來(lái)抑制錯(cuò)誤。但請(qǐng)記住,這樣PHP將無(wú)法通知您使用了錯(cuò)誤的變量名。
// Null coalescing operator echo $value ?? '';
For the ancient PHP versions (< 7.0) isset() with ternary can be used
echo isset($value) ? $value : '';
請(qǐng)注意,盡管這本質(zhì)上是一種錯(cuò)誤抑制,但僅適用于特定的錯(cuò)誤。因此,它可能會(huì)阻止PHP通過(guò)標(biāo)記未初始化的變量來(lái)幫助您。
使用@運(yùn)算符來(lái)抑制錯(cuò)誤。這里為了歷史原因而保留,但嚴(yán)肅地說(shuō),這種情況本不應(yīng)發(fā)生。
注意:強(qiáng)烈建議只實(shí)施第一點(diǎn)。
當(dāng)您(或PHP)嘗試訪問(wèn)數(shù)組的未定義索引時(shí),會(huì)出現(xiàn)此提示/警告。
在處理內(nèi)部數(shù)組時(shí),即在您的代碼中定義的數(shù)組,應(yīng)采取完全相同的態(tài)度:在使用之前初始化所有鍵。這樣,這個(gè)錯(cuò)誤就能夠完成其預(yù)期的工作:通知程序員代碼中的錯(cuò)誤。因此,處理方法是相同的:
建議:聲明數(shù)組元素:
//Initializing a variable $array['value'] = ""; //Initialization value; 0 for int, [] for array, etc. echo $array['value']; // no error echo $array['vaule']; // an error indicates a misspelled key
特殊情況是當(dāng)某個(gè)函數(shù)返回?cái)?shù)組或其他值(如null或false)時(shí)。在嘗試訪問(wèn)數(shù)組元素之前,必須進(jìn)行測(cè)試,例如:
$row = $stmt->fetch(); if ($row) { // the record was found and can be worked with echo $row['name']; }
對(duì)于外部數(shù)組(如$_POST / $_GET / $_SESSION或JSON輸入),情況有所不同,因?yàn)槌绦騿T無(wú)法控制這些數(shù)組的內(nèi)容。因此,檢查某個(gè)鍵是否存在,甚至為缺失的鍵分配默認(rèn)值是合理的。
當(dāng)一個(gè)PHP腳本包含一個(gè)HTML表單時(shí),很自然地,在第一次加載時(shí)沒(méi)有表單內(nèi)容。因此,這樣的腳本應(yīng)該檢查是否提交了表單。
// for POST forms check the request method if ($_SERVER['REQUEST_METHOD'] === 'POST') { // process the form } // for GET forms / links check the important field if (isset($_GET['search'])) { // process the form }
一些HTML表單元素,比如復(fù)選框,如果未被選中,則不會(huì)發(fā)送到服務(wù)器。在這種情況下,使用空合并運(yùn)算符分配默認(rèn)值是合理的。
$agreed = $_POST['terms'] ?? false;
可選的查詢(xún)字符串元素或cookie應(yīng)該以相同的方式處理。
$limit = $_GET['limit'] ?? 20; $theme = $_COOKIE['theme'] ?? 'light';
但是賦值應(yīng)該在腳本的最開(kāi)始進(jìn)行。驗(yàn)證所有的輸入,將其賦值給本地變量,并在代碼中一直使用它們。這樣,你要訪問(wèn)的每個(gè)變量都會(huì)有意地存在。