ftok

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

ftok将路径名和项目标识符转换为 System V IPC 密钥

描述

ftok(string $filename, string $project_id): int

该函数将现有可访问文件的filename和项目标识符转换为用于例如shmop_open()和其他 System V IPC 密钥的integer

参数

filename

可访问文件的路径。

project_id

项目标识符。这必须是一个字符字符串。

返回值

成功时,返回值将是创建的密钥值,否则返回-1

参见

添加说明

用户贡献说明 6 个说明

abk at avatartechnology dot com
20 年前
感谢 [email protected],他从 linux glibc 2.3.2 中获得了这一点:https://php.net/manual/en/function.shmop-open.php - 我把它放在这里是因为它可能对其他人有帮助。

function ftok($pathname, $proj_id) {
$st = @stat($pathname);
if (!$st) {
return -1;
}

$key = sprintf("%u", (($st['ino'] & 0xffff) | (($st['dev'] & 0xff) << 16) | (($proj_id & 0xff) << 24)));
return $key;
}
vlatko dot surlan at evorion dot hr
11 年前
ftok 与 shm 相关函数(如 shmop_open 和 shm_attach)的使用方式相当不直观,可以简单地解释为避免 shm 密钥冲突的需要。使用 ftok 和属于您的项目的某个文件,可能会生成唯一的密钥。此外,使用 ftok 和您的项目中的某个文件,可以避免存储密钥,以便其他进程可以访问该段,因为如果您传递同一个文件,ftok 始终会为您提供相同的密钥。
david dot rech at virusmedia dot de
20 年前
Windows 上缺少 ftok()?这是我的一个小解决方法

<?php
if( !function_exists('ftok') )
{
function
ftok($filename = "", $proj = "")
{
if( empty(
$filename) || !file_exists($filename) )
{
return -
1;
}
else
{
$filename = $filename . (string) $proj;
for(
$key = array(); sizeof($key) < strlen($filename); $key[] = ord(substr($filename, sizeof($key), 1)));
return
dechex(array_sum($key));
}
}
}
?>

注意:即使概率很低,也可能存在重复的密钥。

密钥的计算方式与原始 UNIX ftok() 不一样,因为例如 fileinode() 在 Windows 上也缺失。通常,ftok() 会根据文件 inode 和文件所在的硬盘的系统次要 ID 来计算密钥。

行为类似于 PHP 的 ftok(),如果文件缺失或 $filename 为空,则返回 -1,成功时以十六进制返回计算的 int。

--
此致,
David Rech
mbowie at buzmo dot com
19 年前
如果您打算使用 ftok() 来生成一个 IPC 标识符与其他应用程序共享,请注意 PHP 使用 proj 参数的 ASCII 值来生成密钥,而不是 proj(也称为 id)参数本身。

这样做的结果是,如果您在 PHP 侧使用“1”作为 id,则需要在其他地方使用 49。

这可能并非在所有操作系统下都是如此,但对于 FreeBSD 来说肯定如此,FreeBSD 要求传递给 ftok 的 id 参数为 int。

此外,ipcs 和 ipcrm 对调试 SysV 队列等非常有用。

参考资料
http://www.freebsd.org/cgi/man.cgi?query=ftok
http://www.asciitable.com
seelts at gmail dot com
9 年前
[email protected] 复制了 [email protected] 的代码
但这不正确。
正确的版本在这里
<?php
function ftok ($filePath, $projectId) {
$fileStats = stat($filePath);
if (!
$fileStats) {
return -
1;
}

return
sprintf('%u',
(
$fileStats['ino'] & 0xffff) | (($fileStats['dev'] & 0xff) << 16) | ((ord($projectId) & 0xff) << 24)
);
}
?>

区别在于 $projectId 字符串应该通过 ord() 函数作为 ASCII 值使用。否则,它将被解释为 0。
marco at greenlightsolutions dot nl
17 年前
由于 ftok 只使用文件 inode 的最后 16 位,因此您可能会在大型文件系统上发生冲突。不幸的是,在大型文件系统上,您可能会很快发生冲突:如果您有一组 350-400 个文件,那么很有可能其中两个文件的 inode 的最后 16 位相同。因此,我开始使用 fileinode 代替 ftok,与 shmop_open 等函数一起使用。
To Top