Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP file_exists but rename fails "No such file or directory..."? [closed]

Thinking creation of the file in question lags a bit behind the offending function, I tried running a while loop to buy a little time before calling rename.

$no_file = 1;   
while($no_file && $no_file < 300)
{   // generation of Worksheet.xls may lag behind function -- WAIT FOR IT
    if(file_exists($old_path))
    {   $no_file = 0;
        rename($old_path, $new_path);
    }   else $no_file++;
}
if($no_file) die("Error: Worksheet.xls not found");

In this configuration, I'm thinking rename() can only be called if file_exists() returns true, but for the life of me I can't figure out how / why then rename() gets called and then fails returning...

PHP Warning: rename(C:\wamp\www\demox/wp-content/plugins/cat-man/store-manager/summary/worksheets/Worksheet.xls,C:\wamp\www\demox/wp-content/plugins/cat-man/store-manager/summary/statements/TESTING/2012/Worksheet.xls) No such file or directory...

like image 620
WallabyKid Avatar asked Jan 18 '13 23:01

WallabyKid


2 Answers

It's probably telling you statements/TESTING/2012/ doesn't exist. Create those directories with mkdir() so it will be able to save the file.

mkdir( 'C:\wamp\www\demox/wp-content/plugins/cat-man/store-manager/summary/statements/TESTING/2012/', 777, true);
like image 73
nickb Avatar answered Sep 28 '22 02:09

nickb


However remote, this code opens the possibility of a race condition where your file could change between checking it exists and attempting to rename it. Better to attempt the rename immediately from a try/catch block and deal with failure directly.

You should explicitly exit the loop with a break statement after the rename. And setting $no_file = 0; before the rename is celebrating victory prematurely.

Also, if you're looping with the intention of delaying, you need to sleep execution, otherwise the loop will complete as fast as PHP can process it. Take a look at time_nanosleep. If you time that while loop you'll see it finishes very, very quickly:

$time_start = microtime(true);
$x = 0;
while ($x < 300) {
    file_exists("index.php");
    $x++;
}
echo sprintf("300 loops in %.9f seconds", microtime(true) - $time_start);

// 300 loops in 0.000626087 seconds
like image 37
joemaller Avatar answered Sep 28 '22 03:09

joemaller