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');
}
?>
is_link
(PHP 4, PHP 5)
is_link — Diz se o arquivo é um link simbólico (symbolic link)
Descrição
bool is_link
( string $arquivo
)
Informa se um dado arquivo é um link simbólico (symbolic link).
Parâmetros
- filename
-
O caminho para o arquivo.
Valor Retornado
Retorna TRUE se o nome do arquivo existe e se é um link simbólico, FALSE caso contrário.
Notas
Nota: O resultado desta função é cacheada. Veja clearstatcache() para mais detalhes.
Dica
A partir do PHP 5.0.0, esta função também pode ser utilizada com alguns wrappers URL. Veja List of Supported Protocols/Wrappers para uma lista de quais wrappers são suportados pela família de funções stat().
Veja Também
- is_dir() - Diz se o caminho é um diretório
- is_file() - Informa se o arquivo é um arquivo comum (não é diretório)
- readlink() - Retornar o alvo de um link simbólico
is_link
PaulE
02-Jun-2009 07:03
02-Jun-2009 07:03
foobarfarter
18-Oct-2008 08:06
18-Oct-2008 08:06
@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.
radon8472 at hotmail dot com
01-Aug-2008 02:38
01-Aug-2008 02:38
This function returns "false" for windows *.lnk files (tested under windows XP).
filetype also returns "file" an not "link" like expected.
I didn`t find a solution for this.
mbirth at webwriters dot de
20-May-2008 01:24
20-May-2008 01:24
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.
neverpanic->gmail[com]
30-Dec-2006 08:50
30-Dec-2006 08:50
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)
brendy at gmail dot com
06-May-2006 12:22
06-May-2006 12:22
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 );
}
?>
jr at cnb dot uam dot es
31-May-2005 04:31
31-May-2005 04:31
Why don't you just try
is_dir("$pathname/.")
instead?
If $pathname is a directory, $pathname/. is itself and is a directory too.
If $pathname is a link to a directory, then $pathname/. is the actual directory pointed at and is a directory as well.
If $pathname is a link to a non-directory, then $pathname/. does not exist and returns FALSE, as it should.
A lot easier, more readable and intuitive.
andudi at gmx dot ch
02-Jun-2002 03:44
02-Jun-2002 03:44
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
aris at riponce dot com
27-Mar-2001 08:27
27-Mar-2001 08:27
If you test a symbolic (soft) link with is_file() it will return true. Either use filetype() which always returns the correct type OR make sure that you FIRST test with is_link() before you do with is_file() to get the correct type.
