User Contributed Notes 38 notes

That doesn't rename the file within the folder, as you might assume, instead, it moves the file to whatever the PHP working directory is... Chances are you'll not find it in your FTP tree. Instead, use the following:

As described from the unlink() page:You have to release any handles to the file before you can rename it (True on Windows, at least).This will NOT work, you'll receive permission denied errors:<?php $fileHand = fopen('tempFile.txt', 'r');rename( 'tempFile.txt', 'tempFile2.txt' ); // Permission Denied!?>

rename() fails with PHP4 and PHP5 under Windows if the destination file exists, regardless of file permission settings. I now use a function similar to that of ddoyle [at] canadalawbook [dot] ca, which first tries rename(), checks if it returned FALSE and then uses copy()/unlink() if it failed.

However, copy() is, unlike rename(), NOT useable for "atomic updates". Another process may actually access the destination file while copy() is working. In such a case, the other process with perceive the file as empty or with incomplete content ("half written").

rename() definitely does not follow the *nix rename convention on WinXP with PHP 5. If the $newname exists, it will return FALSE and $oldname and $newname will remain in their original state. You can do something like this instead:

rename() is working on Linux/UNIX but not working on Windows on a directory containing a file formerly opened within the same script. The problem persists even after properly closing the file and flushing the buffer.

Note, that on Unix, a rename is a beautiful way of getting atomic updates to files.

Just copy the old contents (if necessary), and write the new contents into a new file, then rename over the original file.

Any processes reading from the file will continue to do so, any processes trying to open the file while you're writing to it will get the old file (because you'll be writing to a temp file), and there is no "intermediate" time between there being a file, and there not being a file (or there being half a file).

Oh, and this only works if you have the temp file and the destination file on the same filesystem (eg. partition/hard-disk).

Important note - rename() does NOT work for *directories* across filesystems or devices. Only *files*

You will get two warnings:"PHP Warning: rename(): The first argument to copy() function cannot be a directory in <whatever> on line <whatever>""PHP Warning: rename(t2,/var/run/test/t2): Invalid cross-device link in <whatever> on line <whatever>"

The copy() mentioned I assume is C's copy() and not PHP's copy() function. There is an associated bug in the Ubuntu bug system for this as well, that was escalated to bugs.php.net:https://bugs.php.net/bug.php?id=54097

The only workarounds right now I believe is using PHP copy($source, $dest) and then on success, PHP unlink($source), or doing system("mv $source $dest") which is hokey, and should be surrounded by quotes for paths with spaces or other shell metacharacters, and possibly escaped for security.

> rename() may now be able to rename files across partitions on *nix based systemsSeems it's not true.PHP Fatal error: Uncaught exception 'Exception' with message 'rename(/tmp/tables_new/#translit.csv,/home/crmdev/www/bpl-syrena/tables_new/#translit.csv): Operation not permitted'

on windows (XP, vista, 7...) http://fr.wikipedia.org/wiki/Windows-1252", if your file name contains accent, it doesn't work basically. So use iconv function to convert from utf-8 to cp1252 as bellow : <?php

I could not get this to work at first, then saw that I was using a site url constant ahead of my target folder/filename. After re-reading the example I changed my constant to a filesystem type, like <?php rename( old_filename.ext, $_SERVER['DOCUMENT_ROOT']"/target/folder/my_new_filename.ext"); ?> and it worked like a charm.

In Windows, on FAT32, rename will fail with "bad file descriptor" if the underlying short (8.3) file name of the file to rename is the same as the new file name. For example, attempting to rename "Oxygène.m3u" to "Oxygene.m3u" will fail if the 8.3 name of "Oxygène.m3u" is "OXYGENE.M3U" (which is very likely), as Windows will take both names as belonging to the same file. To solve this you must first rename the file to an intermediate name and then rename it to the intended name. To see the short (8.3) file names in a directory you can type DIR /X on a cmd box.

I have programmed a really nice program that remotely lets you manage files as if you have direct access to them (http://sourceforge.net/projects/filemanage/). I have a bunch of really handy functions to do just about anything to files or directories. In it I just finished redevloping the directory move function to utilize PHP's rename() since it is way more efficient than a copy/delete process. It goes through (recursivly) and renames all the files to a new location instead of copying them. It recreates the directory structure in the new location. It also allows you to overwrite the existing files, or not.Here is the function I made; it will likely need tweaking to work as a standalone script, since it relies of variables set by my program (eg: loc1 -- which dynamically changes in my program):

<?PHP// loc1 is the path on the computer to the base directory that may be moveddefine('loc1', 'C:/Program Files/Apache Group/Apache/htdocs', true);

Remark for "php at stock-consulting dot com"'s note:This depends on the operating system.On windows-systems you can't rename a file to an existing destination (ok, with tools you can - but they unlink the exisiting one before).

On WinXP/PHP 5+, not only does rename() not follow the *nix rename as noted below, but other things (do not) happen. If you're trying to rename a directory, files within the directory will NOT be present in the renamed directory, though sub-directories WILL be present. Ultra-strange. And as noted, your 'old' directory will remain on the server totally intact, which can be very confusing.

To try and rename a folder on XP via PHP, I wound up using a workaround: first i used the copydirr() function posted by makarenkoa at ukrpost dot net on the "copy" page of the online manual to copy all folders and files within the original directory to the new one... and then to delete the original directory (and all files/folders beneath it), i used the delDir() function corrected by czambran at gmail dot com on the "rmdir" page of the online manual. Why didn't I use unlink()? Because, unlink does NOT work on Windows systems either (and even if it did work, its not recursive without extra coding).

So, all in all, rename() is pretty much a useless function if you are intending to rename a folder on an XP box.

Actually, I'm pretty sure that rename follows the convention of *nix rename(2) in overwriting the destination if it exists atomically (meaning that no other process will see the destination cease to exist, even for an instant). This is useful because it allows you to build a file as a temp file, then rename it to where you want it to be, and nobody sees the file when it's half done.

Probably rename($old, $new) with an existing new was caused by permission problems. I bet the other problems you had were the result of not calling clearstatcache(), which can cause PHP to act like a file exists though it has since been deleted.

To anyone wondering, rename($old, $new) returns FALSE if $new already exists. My script called for overwriting the file if it existed so I did this:

if(file_exists($new)) { unlink($new); }$ok = rename($old, $new);

This did not work as expected. If $new actually existed then it worked fine. That is the file found at path $new was deleted and replaced with the file found at path $old. However, if $new did NOT exist then the result was the file at path $old vanished into oblivion. After debugging a bit, it seems that rename() was getting executed before the if-statement. So rename() moved $old to $new, THEN the if-statement evaluated to true and deleted the file I just moved. Anyway, this fixed it:

This is an update to the code provided by dev at islam-soft dot com, which renames all files in a directory with a given extension to have a different extension.

I updated four things: Most important, added a check to make sure the extension matched ONLY the end of the filename (the original caused me a number of headaches when it started matching things in the middle of filenames instead of at the end where a proper extension belongs), 2nd added some feedback about what is going on, if you choose verbose mode=TRUE, 3rd added the "testing" parameter so you can do a test run before committing for real, 4th added an error message if a rename fails.

parameter 1 : the directory nameparameter 2 : the first extension which we want to replaceparameter 3 : the new extension of filesparameter 4 : verbose? (true/false)parameter 5 : testing? (true/false)--if true, won't actually rename anything; if you do verbose=TRUE and testing=TRUE you can see what will happen before committing to it with testing=FALSE.

//example usages, first run with $testing set to false, then change $testing to true to do them for real://changeext('your/directory', 'php', 'html', $verbose, $testing);//changeext('your/directory', 'html', 'php', $verbose, $testing);

Apparently rename() will fail on filenames that are too large and emit an E_WARNING.

I was using rename() 'batch-move' a bunch of images. These files were lost in translation; in other words: deleted. One file, however, was moved but the filename was truncated. Weird. Why one or two files while the rest were deleted. This was being attempted on a Windows box.

I hope this helps anyone. If anyone has an explanation please feel free to email me. But if you're one of those idiots who *thinks* they're better than everyone and you *think* you know everything, don't bother.