在一個我已經使用了幾年的腳本(invoiceplane)中,我多次遇到這個錯誤,但不幸的是,它的創建者沒有維護它:
Message: Trying to access array offset on value of type null
我的服務器已經升級到PHP 7.4,我正在尋找一種方法來修復問題并自己維護腳本,因為我對它非常滿意。
這一行給出了錯誤:
$len = $cOTLdata['char_data'] === null ? 0 : count($cOTLdata['char_data']);
$cOTLdata被傳遞給函數:
public function trimOTLdata(&$cOTLdata, $Left = true, $Right = true)
{
$len = $cOTLdata['char_data'] === null ? 0 : count($cOTLdata['char_data']);
$nLeft = 0;
$nRight = 0;
//etc
它包含在mpdf btw中,但是簡單地覆蓋github存儲庫中的文件并不能修復錯誤。
這是因為$cOTLdata為空。PHP以前的版本可能對這種錯誤不太嚴格,會默默地吞下錯誤/通知,而7.4不再這樣做了。
若要檢查$cOTLdata是否為null,請使用is_null():
is_null($cOTLdata)
這意味著這條線應該是這樣的:
$len = is_null($cOTLdata) ? 0 : count($cOTLdata['char_data']);
但是,如果$cOTLdata和$cOTLdata['char_data']都不存在,您可以同時對兩者使用isset():
$len = !isset($cOTLdata['char_data']) ? 0 : count($cOTLdata['char_data']);
此錯誤意味著您試圖使用空值(或不存在的值)作為數組。這肯定意味著你程序的邏輯被破壞了。
首先,你必須明白PHP生成的每一條錯誤信息都是為了幫助你,讓你的代碼更整潔,更少出錯。當您的代碼包含一個bug時,您最好的辦法是修復它,而不是清除它。可悲的是,公認的答案只闡述了后者。但你真的應該考慮做前者。
每條錯誤消息都有助于您找到代碼中的錯誤。這意味著錯誤不應該是故意的或& quot習慣性& quot。這樣你就不必讓他們沉默,每個錯誤都意味著你的代碼確實遇到了一個bug。
就像你的情況。把一個空的或者不存在的變量當作數組來訪問是沒有意義的。只能對數組、特殊類型的對象和字符串(僅使用數字索引)使用數組偏移量。但是如果在期望array的地方得到一個空值,這意味著程序中的數據流中斷了。你需要解決它。
就像你的情況。毫無疑問,$cOTLdata包含null,而您的代碼期望它是一個數組。因此,您需要修復將值賦給$cOTLdata的代碼。
所以,作為一個規則,只要確保每個應該返回一個數組的函數,返回一個數組,或者任何應該包含一個數組的變量,都包含一個數組。并且您不會再看到此錯誤消息。除非,由于某些錯誤,您的代碼將意外地返回一個非數組值。這個錯誤消息將幫助您查明這個問題。
當事情不在你的控制之下時,比如,你需要從一個外部變量中獲取一個數組,先做一個驗證。例如,如果您期望一個來自表單的數組,這是必須的,驗證它并返回一個錯誤,比如
if (!$isset($_POST['options']) || !is_array($_POST['options'])) {
// inform the user ad stop execution
} else {
$options = $_POST['options'];
}
// now you can safely use count() on $options
如果數組是可選的,您可以將其初始化為空數組:
if (!$isset($_POST['options'])) {
$options = [];
} elseif (!is_array($_POST['options'])
// inform the user ad stop execution
} else {
$options = $_POST['options'];
}
// now you can safely use count() on $options
只有在萬不得已的情況下,才可以使用is_null()或isset()來消除這個錯誤
但是你不應該盲目地把它作為一個通用的解決方案。使用isset()不會解決這個問題。它只是把它掩蓋起來,有效地作為錯誤抑制操作符,所以當你的一些函數開始返回不正確的值時,你將永遠不會得到一個有用的錯誤消息來解釋,為什么你的程序突然停止工作。