PHP Conference Japan 2024

ftok

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

ftok將路徑名稱和專案識別碼轉換為 System V IPC 金鑰

描述

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

此函數會將現有可存取檔案的 filename 和專案識別碼轉換為 integer,以便與 shmop_open() 和其他 System V IPC 金鑰一起使用。

參數

filename

可存取檔案的路徑。

project_id

專案識別碼。這必須是一個字元的字串。

回傳值

成功時,回傳值將是建立的金鑰值,否則會回傳 -1

參見

新增註解

使用者貢獻的註解 6 則註解

14
abk at avatartechnology dot com
20 年前
感謝 daniele_dll@yahoo.it 從 linux glibc 2.3.2 取得此內容:https://php.dev.org.tw/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;
}
9
vlatko dot surlan at evorion dot hr
11 年前
ftok 與 shm 相關函式(例如 shmop_open 和 shm_attach)之間相當不直觀的用法可以簡單地解釋為需要避免 shm 金鑰衝突。將 ftok 與屬於您專案的檔案一起使用,可能會產生唯一金鑰。此外,將 ftok 與您專案中的檔案一起使用,可以避免儲存金鑰,以便其他程序可以存取該區段,因為如果您傳遞相同檔案,ftok 將始終提供相同的金鑰。
7
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() 不同,因為 i.e. windows 上也缺少 fileinode()。通常 ftok() 會根據檔案 inode 和檔案所在的硬碟系統次要 ID 來計算金鑰。

行為類似於 PHP 的 ftok(),如果缺少檔案或 $filename 為空,則會回傳 -1,成功時會回傳計算的十六進制整數。

--
問候,
David Rech
2
mbowie at buzmo dot com
20 年前
如果您打算使用 ftok() 產生要與其他應用程式共用的 IPC 識別碼,請注意,PHP 使用 proj 參數的 ASCII 值來產生金鑰,而不是 proj(又名 id)參數本身。

這樣做的結果是,如果您在 PHP 端使用「1」作為 id,則需要在其他地方使用 49。

這可能不適用於所有作業系統,但對於需要傳遞給 ftok 的 id 參數為整數的 FreeBSD 來說,確實如此。

另外值得注意的是,ipcs 和 ipcrm 對於偵錯 SysV 佇列等非常有用。

參考
http://www.freebsd.org/cgi/man.cgi?query=ftok
http://www.asciitable.com
2
seelts at gmail dot com
9 年前
abk@avatartechnology.com 複製了 daniele_dll@yahoo.it 的程式碼
但它不正確。
正確的版本在這裡
<?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。
0
marco at greenlightsolutions dot nl
17 年前
由於 ftok 僅使用檔案 inode 的最後 16 位元,您可能會在大型檔案系統上遇到碰撞。不幸的是,在大型檔案系統上,您可能會相當快地遇到碰撞:如果您有一組 350-400 個檔案,很可能其中兩個檔案的 inode 最後 16 位元相同。因此,我開始使用 fileinode 取代 ftok,用於像 shmop_open 這樣的函式。
To Top