參考-這個錯誤在PHP中意味著什麼?



mysql debugging (20)

這是什麼?

這是關於在編程PHP時可能遇到的警告,錯誤和通知的一些答案,並且不知道如何解決。 這也是一個社區Wiki,所以每個人都被邀請參與添加和維護這個列表。

為什麼是這樣?

諸如“已發送頭文件”“調用非對象成員”等問題經常在堆棧溢出時彈出。 這些問題的根本原因總是相同的。 所以這些問題的答案通常會重複它們,然後顯示OP在他/她的特定情況下要改變哪條線。 這些答案不會給網站增加任何價值,因為它們只適用於OP的特定代碼。 具有相同錯誤的其他用戶不能輕易地從中讀取解決方案,因為它們太本地化。 這很令人傷心,因為一旦你明白了根本原因,糾正錯誤就很簡單。 因此,這份清單試圖以通用的方式解釋解決方案。

我應該在這裡做什麼?

如果您的問題已被標記為與此相同,請在下面找到您的錯誤消息並將修復應用到您的代碼。 答案通常包含進一步的調查鏈接,以防單獨從一般答案中不清楚。

如果您想貢獻,請添加您的“最喜歡的”錯誤消息,警告或通知,每個答案一個,簡短說明它的含義(即使它只是突出顯示手冊頁的術語),一個可能的解決方案或調試方法和一份有價值的現有問答清單。 此外,請隨時改進任何現有答案。

列表

另見


MySQL:你的SQL語法有錯誤; 檢查與您的MySQL服務器版本相對應的手冊,以便在...附近使用正確的語法...

此錯誤通常是由於您忘記正確地轉義傳遞給MySQL查詢的數據而造成的。

該做什麼的例子(“糟糕的想法”):

$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);

此代碼可以包含在帶有表單的網頁中,並提供一個網址,例如http://example.com/edit.php?id=10 (編輯帖子n°10)

如果提交的文本包含單引號,會發生什麼? $query將結束於:

$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';

當這個查詢被發送到MySQL時,它會抱怨語法錯誤,因為中間有一個額外的單引號。

為避免此類錯誤,您必須在查詢中使用之前始終轉義數據。

在SQL查詢中使用之前轉義數據也非常重要,因為如果您不這樣做,您的腳本將開放給SQL注入。 SQL注入可能導致更改,丟失或修改記錄,表或整個數據庫。 這是一個非常嚴重的安全問題!

文檔:


Code doesn't run/what looks like parts of my PHP code are output

If you see no result from your PHP code whatsoever and/or you are seeing parts of your literal PHP source code output in the webpage, you can be pretty sure that your PHP isn't actually getting executed. If you use View Source in your browser, you're probably seeing the whole PHP source code file as is. Since PHP code is embedded in <?php ?> tags, the browser will try to interpret those as HTML tags and the result may look somewhat confused.

To actually run your PHP scripts, you need:

  • a web server which executes your script
  • to set the file extension to .php, otherwise the web server won't interpret it as such*
  • to access your .php file via the web server

* Unless you reconfigure it, everything can be configured.

This last one is particularly important. Just double clicking the file will likely open it in your browser using an address such as:

file://C:/path/to/my/file.php

This is completely bypassing any web server you may have running and the file is not getting interpreted. You need to visit the URL of the file on your web server, likely something like:

http://localhost/my/file.php

You may also want to check whether you're using short open tags <? instead of <?php and your PHP configuration has turned short open tags off.

Also see PHP code is not being executed, instead code shows on the page


Notice: Array to string conversion

This simply happens if you try to treat an array as a string:

$arr = array('foo', 'bar');

echo $arr;  // Notice: Array to string conversion
$str = 'Something, ' . $arr;  // Notice: Array to string conversion

An array cannot simply be echo 'd or concatenated with a string, because the result is not well defined. PHP will use the string "Array" in place of the array, and trigger the notice to point out that that's probably not what was intended and that you should be checking your code here. You probably want something like this instead:

echo $arr[0];  // displays foo
$str = 'Something ' . join(', ', $arr); //displays Something, foo, bar

Or loop the array:

foreach($arr as $key => $value) {
    echo "array $key = $value";
    // displays first: array 0 = foo
    // displays next:  array 1 = bar
}

If this notice appears somewhere you don't expect, it means a variable which you thought is a string is actually an array. That means you have a bug in your code which makes this variable an array instead of the string you expect.


Notice: Trying to get property of non-object error

Happens when you try to access a property of an object while there is no object.

A typical example for a non-object notice would be

$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object

In this case, $users is an array (so not an object) and it does not have any properties.

This is similar to accessing a non-existing index or key of an array (see Notice: Undefined Index ).

This example is much simplified. Most often such a notice signals an unchecked return value, eg when a library returns NULL if an object does not exists or just an unexpected non-object value (eg in an Xpath result, JSON structures with unexpected format, XML with unexpected format etc.) but the code does not check for such a condition.

As those non-objects are often processed further on, often a fatal-error happens next on calling an object method on a non-object (see: Fatal error: Call to a member function ... on a non-object ) halting the script.

It can be easily prevented by checking for error conditions and/or that a variable matches an expectation. Here such a notice with a DOMXPath example:

$result  = $xpath->query("//*[@id='detail-sections']/div[1]");
$divText = $result->item(0)->nodeValue; # Notice: Trying to get property of non-object

The problem is accessing the nodeValue property (field) of the first item while it has not been checked if it exists or not in the $result collection. Instead it pays to make the code more explicit by assigning variables to the objects the code operates on:

$result  = $xpath->query("//*[@id='detail-sections']/div[1]");
$div     = $result->item(0);
$divText = "-/-";
if ($div) {
    $divText = $div->nodeValue;
}
echo $divText;

Related errors:

  • 注意:未定義的索引
  • Fatal error: Call to a member function ... on a non-object

Warning: Division by zero

The warning message 'Division by zero' is one of the most commonly asked questions among new PHP developers. This error will not cause an exception, therefore, some developers will occasionally suppress the warning by adding the error suppression operator @ before the expression. 例如:

$value = @(2 / 0);

But, like with any warning, the best approach would be to track down the cause of the warning and resolve it. The cause of the warning is going to come from any instance where you attempt to divide by 0, a variable equal to 0, or a variable which has not been assigned (because NULL == 0) because the result will be 'undefined'.

To correct this warning, you should rewrite your expression to check that the value is not 0, if it is, do something else. If the value is zero you should not divide, or change the value to 1 and then divide so the division results in the equivalent of having divided only by the additional variable.

if ( $var1 == 0 ) { // check if var1 equals zero
    $var1 = 1; // var1 equaled zero so change var1 to equal one instead
    $var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
    $var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}

Related Questions:


Warning: Illegal string offset 'XXX'

This happens when you try to access an array element with the square bracket syntax, but you're doing this on a string, and not on an array, so the operation clearly doesn't make sense .

例:

$var = "test";
echo $var["a_key"];

If you think the variable should be an array, see where it comes from and fix the problem there.


什麼都看不到。 該頁面是空白的。

也被稱為死亡白色頁面死亡 白色屏幕 。 發生錯誤報告時會發生這種情況,並發生致命錯誤(通常是語法錯誤)。

如果您啟用了錯誤日誌記錄,則可以在錯誤日誌中找到具體的錯誤消息。 這通常位於一個名為“php_errors.log”的文件中,位於中央位置(例如,許多Linux環境中的/var/log/apache2 )或腳本本身的目錄(有時用於共享主機環境)。

有時候可能會更直接地暫時顯示錯誤。 白頁將顯示錯誤消息。 請注意,因為訪問該網站的每個人都可以看到這些錯誤。

這可以通過在腳本的頂部添加以下PHP代碼輕鬆完成:

ini_set('display_errors', 1); error_reporting(~0);

該代碼將打開錯誤顯示並將報告設置為最高級別。

由於ini_set()在運行時執行,所以它對解析/語法錯誤沒有影響。 這些錯誤將出現在日誌中。 如果你想在輸出中顯示它們(例如在瀏覽器中),你必須將display_startup_errors指令設置為true 。 在php.ini.htaccess執行此操作,或通過影響運行時配置的任何其他方法執行此操作

您可以使用相同的方法來設置log_errorserror_log指令來選擇您自己的日誌文件位置。

查看日誌或使用顯示器,您將獲得更好的錯誤消息以及腳本停止的代碼行。

相關問題:

相關錯誤:


注意:使用未定義的常量XXX - 假定為“XXX”

或者在PHP 7.2或更高版本中:

警告:使用未定義的常量XXX--假定為“XXX”(這將在未來版本的PHP中引發錯誤)

在代碼中使用令牌時出現此通知,並且該常見似乎是常量,但未定義該名稱的常量。

此通知最常見的原因之一是未能引用用作關聯數組鍵的字符串。

例如:

// Wrong
echo $array[key];

// Right
echo $array['key'];

另一個常見原因是變量名稱前缺少$ (美元)符號:

// Wrong
echo varName;

// Right
echo $varName;

或者你可能拼寫錯了一些其他常量或關鍵字:

// Wrong
$foo = fasle;

// Right
$foo = false;

當您嘗試訪問由該庫定義的常量時,它也可能表示缺少所需的PHP擴展或庫。

相關問題:


注意:未定義的索引

當您嘗試通過數組中不存在的鍵訪問數組時,會發生。

Undefined Index通知的典型示例是( demo

$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];

spinach1都不存在於陣列中,導致E_WARNING被觸發。

解決方案是確保索引或偏移量在訪問該索引之前存在。 這可能意味著您需要修復程序中的錯誤,以確保這些索引在您期望的時候確實存在。 或者這可能意味著您需要使用array_key_existsisset來測試索引是否存在:

$data = array('foo' => '42', 'bar');
if (array_key_exists('spinach', $data)) {
    echo $data['spinach'];
}
else {
    echo 'No key spinach in array';
}

如果你有這樣的代碼:

<?php echo $_POST['message']; ?>
<form method="post" action="">
    <input type="text" name="message">
    ...

那麼當第一次加載這個頁面時, $_POST['message']不會被設置,你將會得到上述錯誤。 只有在提交表單並且第二次運行此代碼時,數組索引才存在。 你通常用以下方法檢查:

if ($_POST)  ..  // if the $_POST array is not empty
// or
if ($_SERVER['REQUEST_METHOD'] == 'POST') ..  // page was requested with POST

相關問題:


注意:未定義的變量

當您嘗試使用先前未定義的變量時會發生。

一個典型的例子是

foreach ($items as $item) {
    // do something with item
    $counter++;
}

如果您之前未定義$counter ,上面的代碼將觸發通知。

正確的方法是在使用它之前設置變量,即使它只是一個空字符串

$counter = 0;
foreach ($items as $item) {
    // do something with item
    $counter++;
}

相關問題:


致命錯誤:允許XXX字節內存大小用盡(試圖分配XXX字節)

沒有足夠的內存來運行腳本。 PHP已經達到了內存限制並停止執行它。 這個錯誤是致命的,腳本停止。 內存限制的值可以在php.ini文件中配置,也可以使用ini_set('memory_limit', '128 M'); 在腳本中(它將覆蓋在php.ini定義的值)。 內存限制的目的是防止單個PHP腳本吞噬所有可用的內存並導致整個Web服務器停機。

首先要做的是盡量減少腳本所需的內存量。 例如,如果你正在將一個大文件讀入一個變量中,或者正在從數據庫中獲取許多記錄並將它們全部存儲在一個數組中,那麼這可能會佔用大量內存。 將代碼更改為逐行讀取文件或逐個讀取數據庫記錄,而不將它們全部存儲在內存中。 這確實需要一些概念性的知識來了解幕後發生的情況以及數據何時存儲在內存中與其他地方的情況。

如果在您的腳本沒有執行內存密集型工作時發生此錯誤,則需要檢查代碼以查看是否存在內存洩漏。 memory_get_usage函數是你的朋友。

相關問題:

  • 所有“致命錯誤:允許的XXX字節內存大小已耗盡”問題在上

致命錯誤:無法重新聲明class [class name]

致命錯誤:無法重新聲明[函數名稱]

這意味著您要么使用相同的函數/類名稱兩次,需要重命名其中一個名稱,或者是因為您已經使用了requireinclude要使用require_onceinclude_once

當在PHP中聲明一個類或函數時,它是不可變的,並且以後不能用新值聲明。

考慮下面的代碼:

class.php

<?php

class MyClass
{
    public function doSomething()
    {
        // do stuff here
    }
}

的index.php

<?php

function do_stuff()
{
   require 'class.php';
   $obj = new MyClass;
   $obj->doSomething();
}

do_stuff();
do_stuff();

第二次調用do_stuff()會產生上面的錯誤。 通過將require改為require_once ,我們可以確定包含MyClass定義的文件只會被加載一次,並且會避免錯誤。


致命錯誤:調用一個非對象的成員函數...

發生類似於xyz->method()代碼,其中xyz不是對象,因此該method不能被調用。

這是一個致命的錯誤,它將停止腳本(向前兼容性注意:它將成為從PHP 7開始的可捕獲錯誤)。

大多數情況下,這表示代碼缺少錯誤條件檢查。 在調用其方法之前驗證對象實際上是一個對象。

一個typical例子是

// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);

在上面的例子中,查詢無法準備, prepare()會將false賦給$statement 。 試圖調用execute()方法將導致致命錯誤,因為false是一個“非對象”,因為該值是一個布爾值。

找出為什麼你的函數返回一個布爾值而不是一個對象。 例如,檢查$pdo對像是否發生了最後一個錯誤。 有關如何調試的詳細信息取決於如何針對特定功能/對象/類處理錯誤。

如果即使->prepare失敗,那麼你的$pdo數據庫句柄對像也不會被傳入當前範圍 。 找到它的定義。 然後將其作為參數傳遞,將其存儲為屬性,或通過全局範圍共享它。

另一個問題可能是有條件地創建對象,然後嘗試調用該條件塊外部的方法。 例如

if ($someCondition) {
    $myObj = new MyObj();
}
// ...
$myObj->someMethod();

通過試圖在條件塊外執行該方法,可能不會定義您的對象。

相關問題:

  • 調用非對像上的成員函數
  • 列出所有PHP“致命錯誤:調用成員函數...在非對像上”問題

致命錯誤:調用未定義的函數XXX

嘗試調用尚未定義的函數時會發生。 常見原因包括缺少擴展名,包括條件函數聲明,函數聲明中的函數或簡單的拼寫錯誤。

示例1 - 條件函數聲明

$someCondition = false;
if ($someCondition === true) {
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

在這種情況下, fn()永遠不會被聲明,因為$someCondition不是真的。

示例2 - 函數聲明中的函數

function createFn() 
{
    function fn() {
        return 1;
    }
}
echo fn(); // triggers error

在這種情況下,只有在調用createFn()才會聲明fn 。 請注意,隨後對createFn()調用將觸發有關重新聲明現有函數的錯誤。

您也可以看到這是一個PHP內置函數。 嘗試在官方手冊中搜索功能,並檢查它所屬的“擴展”(PHP模塊),以及PHP的哪些版本支持它。

如果缺少擴展名,請安裝該擴展名並在php.ini中啟用它。 您可以使用您的軟件包管理器啟用或安裝擴展程序(例如apt in Debian或Ubuntu, yum Red Hat或CentOS)或者控制面板在共享主機環境中。

如果該函數是從您正在使用的PHP新版本中引入的,則可以在手冊或其評論部分找到指向其他實現的鏈接。 如果它已從PHP中刪除,請查找有關原因的信息,因為它可能不再必要。

如果缺少包含,請確保在調用函數之前包含聲明該函數的文件。

如有錯別字,請修正錯字。

相關問題:

  • https://.com/search?q=Fatal+error%3A+Call+to+undefined+function

解析錯誤:語法錯誤,意外的T_ENCAPSED_AND_WHITESPACE

當整個複雜變量結構不包含在{}時,嘗試引用帶雙引號字符串內引號的數字值時最經常遇到此錯誤。

錯誤情況:

這將導致Unexpected T_ENCAPSED_AND_WHITESPACE

echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^

可能的修正:

在雙引號字符串中,PHP將允許使用未加引號的數組鍵字符串,並且不會發出E_NOTICE 。 所以上面可以寫成:

echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^

整個複雜數組變量和密鑰可以用{}括起來,在這種情況下, 應該引用它們以避免E_NOTICEPHP文檔為複雜變量推薦了這種語法。

echo "This is a double-quoted string with a quoted array key in {$array['key']}";
//--------------------------------------------------------------^^^^^^^^^^^^^^^
// Or a complex array property of an object:
echo "This is a a double-quoted string with a complex {$object->property->array['key']}";

當然,上述任何一種方法的替代方法都是將數組變量連接起來,而不是對其進行插值:

echo "This is a double-quoted string with an array variable " . $array['key'] . " concatenated inside.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^

有關參考,請參閱PHP字符串手冊頁 變量分析部分


解析錯誤:語法錯誤,意外的T_PAAMAYIM_NEKUDOTAYIM

範圍解析運算符也被稱為希伯來語פעמייםנקודתיים中的“Paamayim Nekudotayim”。 意思是“雙冒號”或“雙點雙擊”。

如果您無意中在您的代碼中放入:: ,通常會發生此錯誤。

相關問題:

文檔:


解析錯誤:語法錯誤,意外的T_XXX

當你在意想不到的地方有T_XXX令牌 ,不平衡的(多餘的)圓括號,使用短標籤而不在php.ini中激活它,等等。

相關問題:

進一步的幫助請看:


警告: [函數]期望參數1是資源,布爾給定

警告:mysql_fetch_array()的更一般的變體預計參數1是資源,布爾給定

資源是PHP中的一種type (如字符串,整數或對象)。 資源是一個不透明的blob,它本身沒有固有的有意義的價值。 資源是特定於某些PHP函數或擴展集定義的。 例如,Mysql擴展定義了兩種資源類型

有兩種資源類型在MySQL模塊中使用。 The first one is the link identifier for a database connection, the second a resource which holds the result of a query.

The cURL extension defines another two resource types :

... a cURL handle and a cURL multi handle.

When var_dump ed, the values look like this:

$resource = curl_init();
var_dump($resource);

resource(1) of type (curl)

That's all most resources are, a numeric identifier ( (1) ) of a certain type ( (curl) ).

You carry these resources around and pass them to different functions for which such a resource means something. Typically these functions allocate certain data in the background and a resource is just a reference which they use to keep track of this data internally.

The " ... expects parameter 1 to be resource, boolean given " error is typically the result of an unchecked operation that was supposed to create a resource, but returned false instead. For instance, the fopen function has this description:

Return Values

Returns a file pointer resource on success, or FALSE on error.

So in this code, $fp will either be a resource(x) of type (stream) or false :

$fp = fopen(...);

If you do not check whether the fopen operation succeed or failed and hence whether $fp is a valid resource or false and pass $fp to another function which expects a resource, you may get the above error:

$fp   = fopen(...);
$data = fread($fp, 1024);

Warning: fread() expects parameter 1 to be resource, boolean given

You always need to error check the return value of functions which are trying to allocate a resource and may fail :

$fp = fopen(...);

if (!$fp) {
    trigger_error('Failed to allocate resource');
    exit;
}

$data = fread($fp, 1024);

Related Errors:


警告:mysql_fetch_array()期望參數1是資源,布爾給定

首先和最重要的是:

請不要在新代碼中使用mysql_*函數 。 他們不再被維護並被正式棄用 。 看到紅色框 ? 了解準備好的語句 ,並使用PDOMySQLi - 本文將幫助您決定哪些。 如果您選擇PDO, 這裡是一個很好的教程

當您嘗試從mysql_query的結果中提取數據但查詢失敗時會發生這種情況。

這是一個警告,不會停止腳本,但會使您的程序出錯。

你需要檢查mysql_query by返回的結果

$res = mysql_query($sql);
if (!$res) {
   die(mysql_error());
}
// after checking, do the fetch

相關問題:

相關錯誤:

其他的mysql*函數也會期望一個mysql結果資源作為參數,因為同樣的原因會產生相同的錯誤。


警告:不能修改標題信息 - 已經發送的標題

腳本嘗試向客戶端發送HTTP標頭時會發生,但之前已經輸出,導致標頭已經發送到客戶端。

這是一個E_WARNING ,它不會停止腳本。

一個典型的例子是這樣的模板文件:

<html>
    <?php session_start(); ?>
    <head><title>My Page</title>
</html>
...

session_start()函數將嘗試將包含會話cookie的標題發送給客戶端。 但是PHP在將<html>元素寫入輸出流時已經發送了標題。 你必須將session_start()移動到頂部。

您可以通過在代碼觸發警告查看這些行來解決此問題,並檢查它輸出的位置。 在該代碼之前移動任何標題發送代碼。

一個經常被忽視的輸出是在PHP關閉之後的新行?> 。 當它是文件中的最後一項時,忽略?>被認為是標準做法。 同樣,這個警告的另一個常見原因是,當開始的<?php在它之前有空的空格,行或不可見的字符時,導致web服務器發送頭文件和空白/換行符,因此當PHP開始分析時將無法提交任何標題。

如果你的文件中有多個<?php ... ?>代碼塊,你不應該在它們之間有任何空格。 (注意:如果您的代碼是自動構建的,則可能有多個塊)

還要確保代碼中沒有任何字節順序標記,例如,腳本的編碼是帶有BOM的UTF-8時。

相關問題:





warnings