Search code examples
phpfiledirectorymkdir

mkdir creates a file instead of directory


Assume we have the following tree list:

www _
     \_sources_
      \        \_dir1
       \        \_dir2
        \        \_file
         \_cache

I'm trying to recursively parse each file in the “sources” and copy it into “cache” folder saving the hierarchy, but in my function mkdir() creates a file instead of directory. Outside the function, mkdir() works properly. Here is my function:

function extract_contents ($path)  {
    $handle = opendir($path);
    while ( false !== ($file = readdir($handle)) ) {
    if ( $file !== ".." && $file !== "." ) {
        $source_file = $path."/".$file;
        $cached_file = "cache/".$source_file;
        if ( !file_exists($cached_file) || ( is_file($source_file) && (filemtime($source_file) > filemtime($cached_file)) ) ) {
            file_put_contents($cached_file, preg_replace('/<[^>]+>/','',file_get_contents($source_file)) ); }
        if ( is_dir($source_file) ) {
#  Tried to save umask to set permissions directly – no effect
#           $old_umask = umask(0);
            mkdir( $cached_file/*,0777*/ );
            if ( !is_dir( $cached_file ) ) {
                echo "S = ".$source_file."<br/>"."C = ".$cached_file."<br/>"."Cannot create a directory within cache folder.<br/><br/>"; 
                exit;
                }
# Setting umask back
#           umask($old_umask); 
            extract_contents ($source_file);
            }              
        }
    }
    closedir($handle);
}
extract_contents("sources");

PHP debug gives me nothing but
[phpBB Debug] PHP Notice: in file /var/srv/shalala-tralala.com/www/script.php on line 88: mkdir() [function.mkdir]: ???? ?????????? There is no other lines which are containing mkdir().

ls -l cache/sources looks like
-rw-r--r-- 1 apache apache 8 Mar 31 08:46 file
-rw-r--r-- 1 apache apache 0 Mar 31 08:46 dir1
It's obvious, that mkdir() creates a directory, but it doesn't set "d" flag for it. I just can't understand, why. So at first time, can somebody help and tell me, how to set that flag through octal permissions via chmod(), while i don't see any better solution? (I've already seen man 2 chmod and man 2 mkdir, there is nothing about "d" flag)

addition:
Solved by changind the second if condition to
if ( (!file_exists($cached_file) && is_file($source_file)) || ( is_file($source_file) && (filemtime($source_file) > filemtime($cached_file)) ) )


Solution

  • You are using this :

    file_put_contents($cached_file, preg_replace('/<[^>]+>/','',file_get_contents($source_file)) ); }
    

    Which creates a file called $cached_file.


    And, then, calling that :

    mkdir( $cached_file/*,0777*/ );
    

    There, you try to create a directory called $cached_file.

    But there is already an existing file with that name.
    Which means :

    • mkdir fails, as there is an file with that name
    • and you have a file, the one you created previously with file_put_contents.



    Edit after the comment : just as a test, I'll try creating a file, and a directory with the same name -- using command-line, and not from PHP, to make sure PHP doesn't have any impact on this.

    First let's create a file :

    squale@shark: ~/developpement/tests/temp/plop 
    $ echo "file" > a.txt
    squale@shark: ~/developpement/tests/temp/plop 
    $ ls
    a.txt
    

    And, now, I try creating a directory with the same name a.txt :

    squale@shark: ~/developpement/tests/temp/plop 
    $ mkdir a.txt
    mkdir: impossible de créer le répertoire «a.txt»: Le fichier existe
    

    The error message (sorry, my system is in french) says "impossible to create the directory a.txt : the file already exists"

    So, are you sure you can create a directory with the same name as an existing file ?