is_link
(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() を参照してください。
ヒント
PHP 5.0.0
以降、この関数は、
何らかの URL ラッパーと組合せて使用することができます。
どのラッパーが stat() ファミリーをサポートしているかを調べるには
サポートするプロトコル/ラッパー を参照してください。
+add a note
User Contributed Notes 8 notes
mbirth at webwriters dot de ¶
16 years ago
To find out whether a file is hardlinked to another filename, check the number of links of the stat() output. If it is >1 there is another filename for that file.
To find out whether two filenames are pointing to the same file, check the inode number of those 2 filenames. If it is equal, the 2 filenames are hardlinked together.
PaulE ¶
15 years ago
A workaround for Windows LNK files:
<?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');
}
?>
msaladna at apisnetworks dot com ¶
7 years ago
Careful when using is_link() in thread-safe builds with the self-referential directory entry ".". On ZTS builds is_link("/home/symlink/.") will return true whereas it returns false on non-ZTS builds.
gggeek ¶
11 years ago
On windows, take care that is_link returns false for Junctions.
Ways of telling apart a directory from a junction include doing both a stat() and and lstat() call and checking if there is any difference in the results
neverpanic->gmail[com] ¶
17 years ago
For me (Debian Sarge VPS) is_link returns true even for directories if you don't add a trailing slash to the filename.
<?php
if ($dir{strlen($dir)-1} == '/') $dir = substr($dir, 0, -1);
is_link($dir);
?>
This works for me. It can't detect a symlink somewhere in a complete path, though (i.e. is_link(/www/somedir/file.php) will return false, just as is_link(/www/) would)
foobarfarter ¶
16 years ago
@radon8472 at hotmail dot com
The windows .lnk-things are real files, the explorer only treats them like links. Try to open one with Win+R->"notepad X:\Path\Visiblefilename.lnk You will see much 0-Bytes, but the linked path is displayed right on the screen. It should be possible to do the same by php.
andudi at gmx dot ch ¶
22 years ago
On my SuSE 7.2 is_link does not work on directories, but to find out, if a dir is a link, I use now this:
$linkdir = $path.$linkdirname;
if (realpath($linkdir) != realpath($path)."/".$linkdirname):
//$linkdir is a symbolic linked dir!
...
and this works fine :-)
Andreas Dick
brendy at gmail dot com ¶
18 years ago
On Mac OSX, to see if a file is a FInder alias:
<?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 );
}
?>