is_dir is not correctly recognizing file vs folder

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
silverspy18
Forum Newbie
Posts: 23
Joined: Sun Apr 05, 2009 5:55 pm

is_dir is not correctly recognizing file vs folder

Post by silverspy18 »

Hi all, this is my first post and I am not very experienced in PHP. Anyway, here goes:

I'm trying to write a script that writes out the contents of a folder along with some attributes of the files and folders within it. Here is the top half of the code that seems to be problematic:

Code: Select all

$microtime_0 = microtime();
$dir_to_read = "./";
$dir_to_hide = array(".", "..");
$ext_to_hide = array("htaccess");
$ico_dir = "./ico/";
$date_format = "d-m-y g:i:s a";
 
//Get directory to read if provided in URL and assign a handler to the directory
if (isset($_REQUEST['dir'])) {$dir_to_read = $_REQUEST['dir'];}
$dir_handler = opendir($dir_to_read);
 
//Check that the directory to be read has a / at the end, if not, put one there
if (substr($dir_to_read, -1) != "/") {$dir_to_read .= "/";}
 
//Read the contents of each directory and put files in one array and folders in another
while (false !== ($file_readout = readdir($dir_handler))) {
    if (is_dir($file_readout)) {
        $dir_folders[] = $file_readout;
    } else {
        $delimiter_pos = strpos($file_readout, ".");
        if (false == in_array(ltrim(substr($file_readout, $delimiter_pos), "."), $ext_to_hide)) {
            $dir_files[] = $file_readout;
        }
    }
}
 
// Write out a list of the files and folders (debugging purposes only)
echo("<b>Folders</b>");
foreach ($dir_folders as $key => $value) {
    echo($value."<br />");  
}
 
echo("<b>Files</b>");
foreach ($dir_files as $key => $value) {
    echo($value."<br />");  
}
 
For some reason, and under no particular circumstance that I can identify, files are sometimes identified as folders are are put into the array of folders ($dir_folders) and folders are identified as files. Can anyone offer a solution? Any help would be greatly appreciated since at this point I am completely stuck. Thanks in advance.
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: is_dir is not correctly recognizing file vs folder

Post by requinix »

Does it help you to know that $file_readout doesn't include the directory name? If $dir_to_read is "/dir" then $file_readout won't mention that at all, it'll just be ".", "..", "file", etc.
silverspy18
Forum Newbie
Posts: 23
Joined: Sun Apr 05, 2009 5:55 pm

Re: is_dir is not correctly recognizing file vs folder

Post by silverspy18 »

Hmm, I know that the directory that needs to be read will not be included in $file_readout, however I don't see how this relates to the original issue. I constantly keep getting weird bugs with this code, and I can't see what could be causing a problem. For example, in a particular folder on the server, all of the contents are recognized as files, regardless of whether they are really directories or files. Sometimes only one or two objects are incorrectly identified. 75% of the time the code works well, but random directories are problematic.

For example, a directory "assets" contains the following:
  • New Folder (is treated correctly as a directory)
    img (really is a directory containing five .png files, but is treated as a text file and put into the array with other files)
    New Text Document.txt (treated as a file)


I have the code simplified to the following (with minor changes from the last post):

Code: Select all

 
<?php
$microtime_0 = microtime();
$dir_to_read = "./";
$dir_to_hide = array(".", "..");
$ext_to_hide = array("htaccess");
$ico_dir = "./ico/";
$date_format = "d-m-y g:i:s a";
 
//Get directory to read if provided in URL and assign a handler to the direcotry
if (isset($_REQUEST['dir'])) {$dir_to_read = $_REQUEST['dir'];}
if (substr($dir_to_read, -1) != "/") {$dir_to_read .= "/";}
$dir_handler = opendir($dir_to_read);
 
//Check that the directory to be read has a / at the end, if not, put one there
 
 
//Read the contents of each directory and put files in one array and folders in another
while (false !== ($file_readout = readdir($dir_handler))) {
    if (is_dir($file_readout)) {
        if (false == in_array($file_readout, $dir_to_hide)) {
        $dir_folders[] = $file_readout;
        }
    } else {
        $delimiter_pos = strpos($file_readout, ".");
        if (false == in_array(ltrim(substr($file_readout, $delimiter_pos), "."), $ext_to_hide)) {
            $dir_files[] = $file_readout;
        }
    }
}
 
 
echo '<pre>';
print_r($dir_folders);
print_r($dir_files);
echo '</pre>'
?>
 
...and get the following output...

Code: Select all

 
Array
(
    [0] => New Folder
)
Array
(
    [0] => img
    [1] => New Text Document.txt
)
 
Does any one know of an alternative way of determining whether an object is a file or a directory without using the is_dir or is_file functions?

Thanks.
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: is_dir is not correctly recognizing file vs folder

Post by requinix »

The only way I see that output happening is if there's also a New Folder in the same directory as "assets".

If $file_readout doesn't contain the full path to the file (it's missing the "assets/" part) then is_dir won't get the full picture. While you want it to look at "assets/img" you're only telling it to look for "img". Which might not exist, so is_dir returns false and the code thinks it's a file.
If you used is_file instead you'd see the results reversed - everything becomes a directory.
silverspy18
Forum Newbie
Posts: 23
Joined: Sun Apr 05, 2009 5:55 pm

Re: is_dir is not correctly recognizing file vs folder

Post by silverspy18 »

Thanks a lot tasairis! That fixed the problem, all I had to do was concatenate $dir_to_read in front of $file_readout:

Code: Select all

 
while (false !== ($file_readout = readdir($dir_handler))) {
    if (is_dir($file_readout)) {
        $dir_folders[] = $file_readout;
    } else {
        $delimiter_pos = strpos($file_readout, ".");
        if (false == in_array(ltrim(substr($file_readout, $delimiter_pos), "."), $ext_to_hide)) {
            $dir_files[] = $file_readout;
        }
    }
}
 
changed to:

Code: Select all

 
while (false !== ($file_readout = readdir($dir_handler))) {
    if (is_dir($dir_to_read.$file_readout)) {
        $dir_folders[] = $file_readout;
    } else {
        $delimiter_pos = strpos($file_readout, ".");
        if (false == in_array(ltrim(substr($file_readout, $delimiter_pos), "."), $ext_to_hide)) {
            $dir_files[] = $file_readout;
        }
    }
}
 
Post Reply