关于我下面注释的更正:get_current_user() *不*获取运行脚本的用户名称。相反,它“获取当前 PHP 脚本所有者的名称” - 也就是说,文件的拥有者,而不是进程的拥有者。
要正确获取运行用户,请测试 function_exists('posix_getpwuid'),如果不存在,则假设您在 Windows 上运行并调用 getenv('USERNAME')。
(PHP 4, PHP 5, PHP 7, PHP 8)
posix_getpwuid — 根据用户 ID 返回有关用户的信息
user_id
用户标识符。
返回一个包含以下元素的关联数组
元素 | 描述 |
---|---|
name | name 元素包含用户的用户名。这是一个简短的、通常少于 16 个字符的“句柄”,而不是用户的真实姓名。 |
passwd | passwd 元素包含用户密码的加密格式。通常,例如在使用“影子”密码的系统上,返回一个星号。 |
uid | 用户 ID,应与调用函数时使用的 user_id 参数相同,因此是多余的。 |
gid | 用户的组 ID。使用 posix_getgrgid() 函数来解析组名称及其成员列表。 |
gecos | GECOS 是一个过时的术语,指的是 Honeywell 批量处理系统上的指纹信息字段。然而,该字段仍然存在,其内容已由 POSIX 规范化。该字段包含一个逗号分隔的列表,其中包含用户的全名、办公室电话、办公室号码和家庭电话号码。在大多数系统上,只有用户的全名可用。 |
dir | 此元素包含用户主目录的绝对路径。 |
shell | shell 元素包含用户默认 shell 可执行文件的绝对路径。 |
false
。
示例 #1 posix_getpwuid() 的示例用法
<?php
$userinfo = posix_getpwuid(10000);
print_r($userinfo);
?>
上面的示例将输出类似以下内容
Array ( [name] => tom [passwd] => x [uid] => 10000 [gid] => 42 [gecos] => "tom,,," [dir] => "/home/tom" [shell] => "/bin/bash" )
关于我下面注释的更正:get_current_user() *不*获取运行脚本的用户名称。相反,它“获取当前 PHP 脚本所有者的名称” - 也就是说,文件的拥有者,而不是进程的拥有者。
要正确获取运行用户,请测试 function_exists('posix_getpwuid'),如果不存在,则假设您在 Windows 上运行并调用 getenv('USERNAME')。
我只想要用户名,而不是其他信息。我正在递归遍历目录,需要每个文件或目录的用户名。我使用 stat 获取所需的每个文件属性,这会给我 uid。对每个文件使用 posix_getpwuid() 查询会占用目录中许多文件的大量时间。我设计了一个缓存机制(我认为应该内置)。每次找到新的 uid 时都需要新的查询,这会降低速度,但嘿,你更有可能多次需要一些 uid,因此每次你遇到相同的 uid 时,就不会执行代价高昂的查询。
这是我的代码,随意使用等等。
<?php
$arr_uname = Array();
function file_owner_cached($uid)
{
global $arr_uname;
if (!isset($arr_uname[$uid]))
{
$arr_uname[$uid] = posix_getpwuid($uid)['name'];
}
return $arr_uname[$uid];
}
?>
在 PHP 5.3.19 下,在 Linux 上运行,当然.. 没有在其他任何地方测试。
如果系统也是邮件服务器,并且系统用户拥有具有 PHP 支持的用户目录,则此函数可能会导致系统用户造成的垃圾邮件滥用。
<?php
/* 设置起点和停止位置 */
$start=0;// 第一个用户 ID
$interval=1000;// 将读取的行数
$finishline=3000;// 最后一个用户 ID
$first=(isset($_GET['first'])?$_GET['first']:$start);
$last=(isset($_GET['last'])?$_GET['last']:$interval);
/* 获取和写入逐行用户信息 */
$fp=fopen('copiedpasswd','a');
// copiedpasswd 必须可被 Apache 写入
for ($user=$first;$user<=$last;$user++)
{
$list=posix_getpwuid($user);
if ($list['name']=='') { continue; }
$line=implode(':',$list)."\n";
fputs($fp,$line);
}// 结束 for
fclose($fp);
/* 控制或转发以防止处方 */
if ($last>=$finishline)
{
header("Location: copiedpasswd");
}// 结束 if
else
{
$first += $interval;
$last += $interval;
header("Location: thenameofthisscript.php?first=$first&last=$last");
}// 结束 else
?>
因为 posix_getpwuid(1000) 将返回用户名称(其 ID 为 1000)作为数组的第一个键。
如果您正在使用内核安全模块,例如 LIDS、GrSec 或 Selinux,它只会在运行 PHP/Apache 的用户可以读取 '/etc/passwd' 时起作用,否则您将获得 FALSE。
要获取文件的拥有者的名称,您可以使用以下代码
<?php
$startscript="/var/log/hello.log";
$fileowneruid=fileowner($startscript);
$fileownerarray=posix_getpwuid($fileowneruid);
$fileowner=$fileownerarray['name'];
echo "所有者是 $fileowner";
?>
(我相信你可以用很多方法做到这一点,这是一种我理解的方法,也希望你能理解 :-)).
Rolf
以下是一种获取 uid 用户名的安全方法,即使没有安装 posix 扩展。
<?php
function GetUsernameFromUid($uid)
{
if (function_exists('posix_getpwuid'))
{
$a = posix_getpwuid($uid);
return $a['name'];
}
# 这在 BSD 上有效,但在 GNU 上无效
elseif (strstr(php_uname('s'), 'BSD'))
{
exec('id -u ' . (int) $uid, $o, $r);
if ($r == 0)
return trim($o['0']);
else
return $uid;
}
elseif (is_readable('/etc/passwd'))
{
exec(sprintf('grep :%s: /etc/passwd | cut -d: -f1', (int) $uid), $o, $r);
if ($r == 0)
return trim($o['0']);
else
return $uid;
}
else
return $uid;
}
?>
在 Windows 上,posix_getpwuid() 未实现,但如果您只需要当前用户的用户名,可以使用 get_current_user()。