Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird behaviour of rename() in PHP

I am having a weird problem with my php. Whenever I try to move a file with rename(), not only the file is not moved, but also the directory to which it should be copied is deleted, together with all files within it. The original code is:

rename('temp.odt', 'tmp/report.odt');

but I have already tried other path delimiters like

rename('temp.odt', 'tmp\report.odt');

rename('temp.odt', 'tmp\\report.odt');

rename('temp.odt', 'tmp' . DIRECTORY_SEPARATOR . 'report.odt');

rename('C:\wamp\www\zaiko\temp.odt', 'C:\wamp\www\zaiko\tmp\report.odt');

all to no avail. The code comes from a 3rd-party module which is used in the system I am working on.

Points well checked:

  1. The file 'temp.odt' does exist in the current directory;
  2. The directory 'tmp' does exist and there are several files in it. Also it is not read only.
  3. The target file does not already exist (the actual file name has a timestamp, I reduced it here for simplicity)

After running rename(), the 'temp.odt' file is intact in its original location, while the folder 'tmp' is vanished as well as everything inside it. The following warning is issued:

( ! ) Warning: rename(temp.odt,tmp\report.odt) [function.rename]: The system couldn't find the specified path*. (code: 3) in C:\wamp\www\zaiko\modules\mod_deliver.php on line 192

*translated from Portuguese

Running: Apache 2.2.17 with PHP 5.3.5 on Windows XP with NTFS


Editing:

Just found the cause of the problem. It turns out that the module used by the application uses, in turn, a compression library; this library uses a temporary folder with exactly the same name as the one used by the application.

It must use some sort of cache, which would explain why the error didn't appear 100% times.

Problem solved by changing the name of the 'tmp' folder to anything else.

Thank you all for your time, and sorry for bothering you with such a stupid thing that, as it turns out, had absolutely nothing to do with my initial guess and, consequently, with the question formulated.

like image 396
Sérgio Domingues Avatar asked Feb 13 '12 07:02

Sérgio Domingues


1 Answers

The example on PHP.net tells you exactly what to do - use the ROOT PATH to the file - normally this can be got by using $_SERVER['DOCUMENT_ROOT'] (but this only goes to the htdocs/public_html directory - you need to specify the rest) or by manually typing the path in (but try to avoid this).

<?php
rename("/tmp/tmp_file.txt", "/home/user/login/docs/my_file.txt");
?>

At a guess, the following should work (assuming this is your path) - this also checks that your file actually exists so it can be renamed - you need to make sure that tmp/ actually exists in the first place, but you will get an error popping out if it didn't:

<?php

$root = getcwd().DIRECTORY_SEPARATOR; // Obtain the current working dir
$srcpath = $root."temp.odt";          // The file you want to rename
$destpath = $root."tmp/report.odt";   // Where you want to rename the file to

// make sure file exists and its movable
if(is_writable($srcpath)){
    // if it exists, rename it
    rename($srcpath, $dstpath);
    echo "File was renamed!";
} else {
    echo "It seems that the specified file doesn't exist!";
}
?>

You were escaping characters by using backslashes - always use forward slashes (I know this is within a single quote, which is ok, but if you use double quote then you would wonder what's gone wrong)!

like image 58
MrJ Avatar answered Oct 26 '22 09:10

MrJ