要找出檔案是否已硬連結到另一個檔案名稱,請檢查 stat() 輸出的連結數。如果它 >1,則表示該檔案還有另一個檔案名稱。
要找出兩個檔案名稱是否指向同一個檔案,請檢查這兩個檔案名稱的 inode 編號。如果它們相等,則兩個檔案名稱已硬連結在一起。
(PHP 4, PHP 5, PHP 7, PHP 8)
is_link — 判斷檔案名稱是否為符號連結
filename
檔案的路徑。
失敗時,會發出 E_WARNING
。
範例 #1 建立並確認檔案是否為符號連結
<?php
$link = 'uploads';
if (is_link($link)) {
echo readlink($link);
} else {
symlink('uploads.php', $link);
}
?>
注意:此函數的結果會被快取。詳情請見 clearstatcache()。
要找出檔案是否已硬連結到另一個檔案名稱,請檢查 stat() 輸出的連結數。如果它 >1,則表示該檔案還有另一個檔案名稱。
要找出兩個檔案名稱是否指向同一個檔案,請檢查這兩個檔案名稱的 inode 編號。如果它們相等,則兩個檔案名稱已硬連結在一起。
Windows LNK 檔案的解決方法
<?php
function _is_link($filename)
{
if(is_link($filename))
return true;
$ext = substr(strrchr($filename, '.'), 1);
if(strtolower($ext) == 'lnk')
{
return (_readlink($filename) ? true : false);
}
return false;
}
function _readlink($file)
{
if(file_exists($file))
{
if(is_link($file))
{
return readlink($file);
}
// Get file content
$handle = fopen($file, "rb");
$buffer = array();
while(!feof($handle))
{
$buffer[] = fread($handle, 1);
}
fclose($handle);
// Test magic value and GUID
if(count($buffer) < 20)
return false;
if($buffer[0] != 'L')
return false;
if((ord($buffer[4]) != 0x01) ||
(ord($buffer[5]) != 0x14) ||
(ord($buffer[6]) != 0x02) ||
(ord($buffer[7]) != 0x00) ||
(ord($buffer[8]) != 0x00) ||
(ord($buffer[9]) != 0x00) ||
(ord($buffer[10]) != 0x00) ||
(ord($buffer[11]) != 0x00) ||
(ord($buffer[12]) != 0xC0) ||
(ord($buffer[13]) != 0x00) ||
(ord($buffer[14]) != 0x00) ||
(ord($buffer[15]) != 0x00) ||
(ord($buffer[16]) != 0x00) ||
(ord($buffer[17]) != 0x00) ||
(ord($buffer[18]) != 0x00) ||
(ord($buffer[19]) != 0x46))
{
return false;
}
$i = 20;
if(count($buffer) < ($i + 4))
return false;
$flags = ord($buffer[$i]);
$flags = $flags | (ord($buffer[++$i]) << 8);
$flags = $flags | (ord($buffer[++$i]) << 16);
$flags = $flags | (ord($buffer[++$i]) << 24);
$hasShellItemIdList = ($flags & 0x00000001) ? true : false;
$pointsToFileOrDir = ($flags & 0x00000002) ? true : false;
if(!$pointsToFileOrDir)
return false;
if($hasShellItemIdList)
{
$i = 76;
if(count($buffer) < ($i + 2))
return false;
$a = ord($buffer[$i]);
$a = $a | (ord($buffer[++$i]) << 8);
}
$i = 78 + 4 + $a;
if(count($buffer) < ($i + 4))
return false;
$b = ord($buffer[$i]);
$b = $b | (ord($buffer[++$i]) << 8);
$b = $b | (ord($buffer[++$i]) << 16);
$b = $b | (ord($buffer[++$i]) << 24);
$i = 78 + $a + $b;
if(count($buffer) < ($i + 4))
return false;
$c = ord($buffer[$i]);
$c = $c | (ord($buffer[++$i]) << 8);
$c = $c | (ord($buffer[++$i]) << 16);
$c = $c | (ord($buffer[++$i]) << 24);
$i = 78 + $a + $b + $c;
if(count($buffer) < ($i +1))
return false;
$linkedTarget = "";
for(;$i < count($buffer); ++$i)
{
if(!ord($buffer[$i]))
break;
$linkedTarget .= $buffer[$i];
}
if(empty($linkedTarget))
return false;
return $linkedTarget;
}
return false;
}
if(_is_link('test.lnk'))
{
echo _readlink('test.lnk');
}
?>
在使用執行緒安全的建置版本中使用 is_link() 時,請注意自我參照目錄項目 "."。在 ZTS 建置版本中,is_link("/home/symlink/.") 將返回 true,而在非 ZTS 建置版本中則返回 false。
在 Windows 上,請注意 is_link 對 Junction 返回 false。
區分目錄和 Junction 的方法包括執行 stat() 和 lstat() 呼叫,並檢查結果是否有任何差異。
對我來說(Debian Sarge VPS),如果沒有在檔案名稱後加上斜線,即使是目錄,is_link 也會返回 true。
<?php
if ($dir{strlen($dir)-1} == '/') $dir = substr($dir, 0, -1);
is_link($dir);
?>
這個方法對我有用。 但它無法偵測完整路徑中的符號連結(例如,is_link(/www/somedir/file.php) 會回傳 false,就像 is_link(/www/) 一樣)
@radon8472 at hotmail dot com
Windows 的 .lnk 檔案是真實的檔案,檔案總管只是將它們視為連結。 試著用 Win+R->"notepad X:\Path\Visiblefilename.lnk" 開啟一個 .lnk 檔案,你會看到很多 0 位元組,但連結的路徑會顯示在螢幕上。 PHP 應該也可以做到這一點。
在我的 SuSE 7.2 上,is_link 無法用於目錄,但為了找出目錄是否為連結,我現在使用這個方法
$linkdir = $path.$linkdirname;
if (realpath($linkdir) != realpath($path)."/".$linkdirname)
//$linkdir 是一個符號連結目錄!
...
而且這個方法有效 :-)
Andreas Dick
在 Mac OSX 上,要查看檔案是否為 Finder 別名
<?PHP
if( getFinderAlias( $someFile , $target ) ) {
echo $target;
}
else {
echo "檔案不是別名";
}
function getFinderAlias( $filename , &$target ) {
$getAliasTarget = <<< HEREDOC
-- BEGIN APPLESCRIPT --
set checkFileStr to "{$filename}"
set checkFile to checkFileStr as POSIX file
try
tell application "Finder"
if original item of file checkFile exists then
set targetFile to (original item of file checkFile) as alias
set posTargetFile to POSIX path of targetFile as text
get posTargetFile
end if
end tell
end try
-- END APPLESCRIPT --
HEREDOC;
$runText = "osascript << EOS\n{$getAliasTarget}\nEOS\n";
$target = trim( shell_exec( $runText ) );
return ( $target == "" ? false : true );
}
?>