PHP Conference Japan 2024

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 函数设置的错误号。可以使用 posix_strerror() 检查与 errno 关联的系统错误消息。

参数

此函数没有参数。

返回值

返回上次失败的 posix 函数设置的 errno(错误号)。如果不存在错误,则返回 0。

示例

示例 #1 posix_get_last_error() 示例

此示例尝试终止一个错误的进程 ID,这将设置最后一个错误。然后我们将打印出最后一个 errno。

<?php
posix_kill
(999459,SIGKILL);
echo
'Your error returned was '.posix_get_last_error(); //Your error was ___
?>

参见

添加注释

用户贡献的注释 1 条注释

4
anajilly at gmail dot com
10 年前
许多 posix 函数在发生错误时会在 errno 代码中提供非常有用的信息。例如,stream_select() 在生成错误时,根据手册页 (man 2 select) 可能返回四个不同的错误之一,这些错误列为:EBADF、EINTR、EINVAL、ENOMEM。请参阅手册页以获取有关这些错误的更具体信息。在此示例中,当 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 手册页中列出的这些错误常量不是 PHP 接口的一部分。当您调用 posix_get_last_error() 时,它将返回一个整数。获取未命名整数返回代码的问题在于,这些整数在不同的系统上可能意味着不同的东西。您可以(并且可能应该)将结果整数传递给 posix_strerror() 函数,该函数将返回对错误是什么的准确易于理解的描述。这当然很有用,但主要用于日志记录。(错误的字符串描述比实际的整数数值代码更容易更改。)确实,在使用 posix_errno() 的结果时,最好针对一组可能的常量检查该值。如前所述,您将它们与之比较的常量是特定于系统的,因此您需要在该系统上查找它们。这是一个简单可靠的方法。

查看 errno 手册页($ 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);
// ... etc. etc.
}
===================================

现在,如果您只是通过 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