I have a symlink on my Windows server which was made like this:
F:\>mkdir link-target
F:\>mklink /D link f:\link-target
(Note the lower case f:
in the symlink target)
In PHP I run this:
$dir = realpath('f:\link');
var_dump($dir);
$dir = realpath($dir);
var_dump($dir);
Which outputs:
string 'f:\link-target' (length=14)
string 'F:\link-target' (length=14)
Notice the change in case on the second realpath.
Is this a bug, or intended? And whats the best way to work around it?
It is breaking a case like this:
function check_link($to, $from) {
if (realpath($to) !== realpath($from)) {
...
}
}
Which is used to check $to
exists, and is linked to $from
.
- PHP 5.4
- Windows 7
Edit:
I need consistent behavior on both Windows and Linux, and have the following work around be its pretty nasty:
if (realpath($from) === false) {
} elseif (realpath($to) === false) {
} else {
do {
$to = realpath($to);
} while (realpath($to) !== false && $to !== realpath($to));
do {
$from = realpath($from);
} while (realpath($from) !== false && $from !== realpath($from));
if ($to !== $from) {
...
}
}
Edit 2:
On furter investigation I have noticed that on Windows symlinks are only followed 1 level deep:
// F:\>mkdir link-target
// F:\>mklink /D link f:\link-target
// F:\>mklink /D link2 f:\link
$dir = realpath('f:\link2');
var_dump($dir);
$dir = realpath($dir);
var_dump($dir);
$dir = realpath($dir);
var_dump($dir);
// string 'f:\link' (length=7)
// string 'f:\link-target' (length=14)
// string 'F:\link-target' (length=14)