2024 年日本 PHP 研討會

posix_get_last_error

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

posix_get_last_error擷取最後一個失敗的 posix 函式所設定的錯誤號碼

說明

posix_get_last_error(): int

擷取最後一個失敗的 posix 函式所設定的錯誤號碼。與 errno 相關聯的系統錯誤訊息可以使用 posix_strerror() 檢查。

參數

此函式沒有參數。

傳回值

傳回最後一個失敗的 posix 函數所設定的 errno(錯誤代碼)。如果沒有錯誤,則傳回 0。

範例

範例 #1 posix_get_last_error() 範例

此範例嘗試結束一個不存在的行程 ID,這將設定最後一個錯誤。然後我們將印出最後的 errno。

<?php
posix_kill
(999459,SIGKILL);
echo
'您的錯誤代碼為 '.posix_get_last_error(); //您的錯誤代碼為 ___
?>

另請參閱

新增註記

使用者貢獻的註記 1 則註記

anajilly at gmail dot com
10 年前
許多 posix 函數在發生錯誤時,會在 errno 代碼中提供非常有用的資訊。例如,根據 man 頁面 (man 2 select),stream_select() 產生錯誤時,可能會傳回四種不同錯誤之一,分別列為:EBADF、EINTR、EINVAL、ENOMEM。有關這些錯誤的更詳細資訊,請參閱 man 頁面。在此範例中,當 stream_select() 函數傳回 false 時,posix_get_last_error() 將傳回一個非零值,該值將被設定為這些常數之一。例如,如果 stream_select() == false 且 posix_get_last_error() == EBADF,則提供給 select() 函數的檔案描述符之一可能已以某種方式關閉。另一方面,如果 posix_get_last_error() 傳回 EINTR,則 stream_select() 傳回 FALSE 並非因為任何真正的錯誤狀況,而僅僅是因為行程處理了一個信號。當信號在 stream_select() 阻塞時到達,它將始終停止阻塞並立即傳回 false。這種行為是合理的,儘管看起來可能不太方便。您只需要正確處理它。(在 php 中,並非很多人這樣做。)

從這個例子中,應該很清楚,至少應該考慮以不同的方式處理不同的錯誤類型。例如,應該忽略 EINTER,除非您的程式使用信號來開啟或關閉檔案控制代碼或通訊端。

相關 POSIX man 頁面中列出的這些錯誤常數不是 PHP 介面的一部分。當您呼叫 posix_get_last_error() 時,它將傳回一個整數。取得未命名整數傳回代碼的問題是,這些整數在不同的系統上可能代表不同的含義。您可以(而且可能應該)將產生的整數傳遞給 posix_strerror() 函數,該函數將傳回錯誤的準確人類可讀描述。這當然很有用,但主要用於記錄。(錯誤的字串描述比實際的整數值代碼更容易更改。)實際上,使用 posix_errno() 的結果時,最好根據一組可能的常數檢查該值。如前所述,您與之比較的常數是系統特定的,因此您需要在該系統上查詢它們。這裡有一個簡單可靠的方法可以做到這點。

查看 errno man 頁面($ man errno)並將所有常數名稱複製到一個非常基本的 C 檔案中,如下所示。

===================================
#include <errno.h>
#include <stdio.h>
int main(){
printf("define('E2BIG', %d);\n", E2BIG);
printf("define('EACCES', %d);\n", EACCES);
printf("define('EADDRINUSE', %d);\n", EADDRINUSE);
printf("define('EADDRNOTAVAIL', %d);\n", EADDRNOTAVAIL);
// ... 等等。
}
===================================

現在,如果您僅透過 C 預處理器執行這段程式碼(例如:'gcc -E cfile.c'),那麼這些常數名稱將會被系統上使用的數字取代。(警告:執行 C 編譯器/預處理器需要在將執行 PHP 程式碼的系統上進行。請注意是否正在使用 nfs 或其他類似機制,這些機制可能會將您的編碼環境與執行環境分開。)除了執行 C 預處理器之外,您也可以直接編譯並執行上述程式(例如:'gcc cfile.c && ./a.out')。執行它將會產生一份與 PHP 相容的 define() 呼叫列表,這些呼叫會在目標系統上的 PHP 程式中正確定義這些常數,因此將可使用。只需將這些定義複製到一個 php 檔案中即可。

為了完成這個範例,您可以像這樣使用這些常數:

$selret = stream_select( $r, $w, $e, $to );
if( $selret === false )
{
switch( posix_get_last_error() )
{
case EBADF: /* 其中一個控制代碼有問題。修復它。 */ break;
case EINVAL: /* $to 是負數?糟糕。 */ break;
case ENOMEM
throw new exception("可能發生記憶體洩漏。請重新啟動。");
break;
case EINTR
break; // 通常在 select() 之後忽略 EINTR 是沒問題的。
}
}
To Top