关于我下面注释的更正: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 的 userdirs,则此函数可能会导致由系统用户造成的垃圾邮件滥用。
<?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;
}
?>