2

Windowsサーバーに次のように作成されたシンボリックリンクがあります。

F:\>mkdir link-target
F:\>mklink /D link f:\link-target 

f:(シンボリックリンクターゲットの小文字に注意してください)

PHPではこれを実行します:

$dir = realpath('f:\link');
var_dump($dir);

$dir = realpath($dir);
var_dump($dir);

どの出力:

string 'f:\link-target' (length=14)
string 'F:\link-target' (length=14)

2番目のリアルパスの大文字小文字の変更に注意してください。

これはバグですか、それとも意図されたものですか?そして、それを回避するための最良の方法は何ですか?

それはこのようなケースを壊しています:

function check_link($to, $from) {
    if (realpath($to) !== realpath($from)) {
        ...
    }
}

チェックに使用されるもの$toが存在し、にリンクされてい$fromます。

  • PHP 5.4
  • Windows 7

編集:

WindowsとLinuxの両方で一貫した動作が必要であり、次の回避策がかなり厄介です。

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) {
        ...
    }
}

編集2:

さらに調査したところ、Windowsではシンボリックリンクは1レベルの深さでしかフォローされていないことに気づきました。

// 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)
4

2 に答える 2

1

結局のところ

do {
    $to = realpath($to);
} while (realpath($to) !== false && $to !== realpath($to));

唯一の方法です。

https://bugs.php.net/bug.php?id=61933

于 2012-05-07T20:19:40.800 に答える
0

これはよく考えれば当然のことです。最初のパス解決では、リンク ターゲットとして定義されたものを見つけます。2 つ目については、同じパスになりますが、ドライブ文字に適切な大文字が使用されています。

Windows ファイル システムでは、パス/ファイル名は大文字と小文字が区別されません。それらを比較するには、テストする前に両方を大文字または小文字に変換してください。

if (strtoupper(realpath($to)) !== strtotupper(realpath($from))) {
于 2012-05-02T17:22:19.447 に答える