PHP function 'scandir' shows deleted directory when deleted directory was open in Windows Explorer
I am running Apache HTTP server 2.4 on a Windows Server 2008 R2 machine with PHP 5.4.4.
I have the following directory structure on myE:\
drive:
E:\Dir1\Dir2\Dir3
All of the directories (Dir1
,Dir2
andDir3
) are empty (they have no files) except for the child directories shown above.
I am trying to deleteDir3
and then look at the contents of directoryDir2
to make sure that there's nothing there. I have written the following PHP script to test this:
<?php
$currentDir = "E:\\Dir1\\Dir2\\Dir3";
$parentDir = dirname( $currentDir ); // Get the parent directory for Dir3.
rmdir ( $currentDir ); // Remove directory Dir3.
echo "<b>Current directory:</b> " . $currentDir . " <b><< I don't exist, I was just deleted.</b><br />";
echo "<b>Parent directory:</b> " . $parentDir. "<br />";
echo "<b>According to 'scandir', the parent directory contains:</b> ";
print_r( scandir( $parentDir, SCANDIR_SORT_NONE ) );
echo "<br /><br />";
?>
If I do not haveDir3
open in Windows Explorer, the script above woks perfectly and delivers the following output:
Current directory: E:\Dir1\Dir2\Dir3 << I don't exist, I was just deleted.
Parent directory: E:\Dir1\Dir2
According to 'scandir', the parent directory contains: Array ( [0] => . [1] => .. )
However, if I haveDir3
open in Windows Explorer, I get the following output:
Current directory: E:\Dir1\Dir2\Dir3 << I don't exist, I was just deleted.
Parent directory: E:\Dir1\Dir2
According to 'scandir', the parent directory contents: Array ( [0] => . [1] => .. [2] => Dir3 )
Notice thatDir3
appears in the array of contents forDir2
. In other words,scandir()
thinks thatDir3
still exists even when I know for a fact that it doesn't (Windows explorer kicks me back toDir2
).
Does anyone know why this is happening?
Answer
Solution:
When you have the directory opened in windows explorer. There is an existing
handle
to thedirectory
in theOS-es memory
.Scandir
internally fetches details of directory/file existence from the OS. So when the directory is open and you delete it and run ascandir
immediately, then windows returns it because there is a"lock"
on the directory handle. This handle closes only when you close the directory (or some internal garbage collections happens at the OS level I guess). When the directory is not open in windows explorer none of these edge cases are happening and so everything works like a charm.Again one of the behaviors of windows. I think
clearstatcache()
is an option, but I believe it works only onposix-compliant
Os-es and alsoscandir()
is not affected by it.