要了解文件是否硬链接到另一个文件名,请检查 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" 打开一个。你会看到很多 0 字节,但链接路径会直接显示在屏幕上。应该可以用 PHP 做同样的事情。
在我的 SuSE 7.2 上,is_link 无法在目录上使用,但要找出目录是否为链接,我现在使用以下方法
$linkdir = $path.$linkdirname;
if (realpath($linkdir) != realpath($path)."/".$linkdirname)
//$linkdir 是一个符号链接的目录!
...
并且这工作得很好 :-)
安德烈亚斯·迪克
此函数对于 Windows *.lnk 文件返回 "false"(在 Windows XP 下测试)。
filetype 也返回 "file" 而不是 "link",这与预期不符。
我还没有找到解决办法。
在 Mac OSX 上,要查看文件是否为 Finder 别名
<?PHP
if( getFinderAlias( $someFile , $target ) ) {
echo $target;
}
else {
echo "File is not an alias";
}
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 );
}
?>