php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65697 is_link not working with windows junctions
Submitted: 2013-09-18 12:51 UTC Modified: 2013-09-18 20:34 UTC
From: giunta dot gaetano at gmail dot com Assigned:
Status: Not a bug Package: *Directory/Filesystem functions
PHP Version: 5.4.19 OS: win7 64bit
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: giunta dot gaetano at gmail dot com
New email:
PHP Version: OS:

 

 [2013-09-18 12:51 UTC] giunta dot gaetano at gmail dot com
Description:
------------
is_link seems to return false for junction points which show up as <JUNCTION> when using the DIR command.
It seems to work for junctions which show up as <SYMLINKD> when using the DIR command.

tested on php 5.3.27 and 5.4.14 (32 bit of course)

Test script:
---------------
<?php

$paths = array(
  "linksource",
  "linktarget",
  "linktarget2"
);

foreach ( $paths as $path )
{
  echo "----\n $path\n";
  var_dump( is_link( $path ) );
  var_dump( is_dir( $path ) );
  var_dump( array_diff( stat($path), lstat($path) ) );
}

Expected result:
----------------
results of DIR command:

07/09/2013  15:59    <DIR>          linksource
07/09/2013  19:11    <JUNCTION>     linktarget [D:\htdocs\linksource]
18/09/2013  14:30    <SYMLINKD>     linktarget2 [linksource]

Actual result:
--------------
D:\htdocs>php linktest.php
----
 linksource
bool(false)
bool(true)
array(0) {
}
----
 linktarget
bool(false)
bool(true)
array(8) {
  [2]=>
  int(16895)
  [8]=>
  int(1378562389)
  [9]=>
  int(1378562389)
  [10]=>
  int(1378562389)
  ["mode"]=>
  int(16895)
  ["atime"]=>
  int(1378562389)
  ["mtime"]=>
  int(1378562389)
  ["ctime"]=>
  int(1378562389)
}
----
 linktarget2
bool(true)
bool(true)
array(8) {
  [2]=>
  int(16895)
  [8]=>
  int(1378562389)
  [9]=>
  int(1378562389)
  [10]=>
  int(1378562389)
  ["mode"]=>
  int(16895)
  ["atime"]=>
  int(1378562389)
  ["mtime"]=>
  int(1378562389)
  ["ctime"]=>
  int(1378562389)
}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-09-18 19:00 UTC] pajoye@php.net
-Status: Open +Status: Not a bug
 [2013-09-18 19:00 UTC] pajoye@php.net
Junctions are not symlinks, the result is correct. Also the 
junctions pointing to a directory may work. I remember 
some windows version specific changes here, where it 
ended as symlink or junction (recent always do it as 
symlonk afair)
 [2013-09-18 20:13 UTC] giunta dot gaetano at gmail dot com
Mmm, if it walks like a duck and quacks like a duck...

For all scenarios I can figure (backups, deploying code using symlinks), treating a junction as a symlink makes more sense than not doing it.

Right now the only way to tell if a folder is actually a "real one" or not is to use the array_diff trick I put in the test script. It looks hackish, cumbersome, and why should lstat() treat a junction differently than is_link()  anyway?)

It is true that windows versions starting with Vista do create symlinks by default, but tools like "Link Shell Extension" or the venerable sysinternals junction.exe still allow one to create Junctions.
 [2013-09-18 20:21 UTC] pajoye@php.net
It is not about making sense or not. It is about backward compability and how they 
actually behave from a file system point of view.

Think of junction like hard links. You can't see hard link with is_link, no matter 
the platform.
 [2013-09-18 20:34 UTC] giunta dot gaetano at gmail dot com
Ok, then be it
 [2017-03-22 12:20 UTC] finitor at gmail dot com
<?php
$link = symlink('a', 'b');
is_link($link);// Return FALSE
?>

PHP can not detect symlinks that it creates.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC