How to move files with special characters?

I want to move files on a windows machine with special characters in it. The characters already exist in the file and folder names, but my php script will not copy them to another directory. I am NOT trying to display this online, and all the help I can find is about setting the right headers for browsers, which isn’t relevant here.

Files without special characters copy and move just fine. Some sample code:



$file = '★'
$new_file_path = 'path_to_dir' . $file.

	if (!rename($file, $new_file_path))
	{
		echo "file did not copy correctly";
	}




Is the issue that the special character you type in to the php source code is not being decoded in the same way that the filesystem expects it to be? That is, is it interpreting your square-box as something else, and therefore cannot find the file. Is there any kind of directory.open() and directory.read() equivalent that you could use to get the filenames instead of typing directly into the source?

I had a quick google but the general view seems to be that it’s not a good thing to do, though there was a note on StackOverflow that suggested using urlencoding when dealing with special characters.

I am getting the files/paths from a directory using the recursive directory iterator. I then get rid of their current path and pre-pend a new path to the files, and attempt to move them there. The code above is just a quick example because the actual program is much larger.

I am getting ?? in place of special characters.

Windows itself has no problem displaying the files, and I can copy and move them manually okay.

The problem is that PHP under Windows is a non-Unicode-aware program so it cannot access files having characters from the Unicode character set, it accesses them using an encoding that corresponds to the currently selected system locale. If you are working with special characters which are part of the currently selected Windows locale then you can use iconv to do the conversions where necessary. However, this is not always easy, you can read more about this problem here.

I once stumbled upon this problem - files were perfectly accessible by their UTF-8 names under Linux but in Windows I had to convert them to one of the Windows encodings to be able to access them within PHP. But I don’t really know how to cope with it if you want your PHP application to be portable, that is to work for everybody under any locale and for all Unicode filenames.

Wow, I didn’t realize that this was such a problem for PHP. I’ve been using PHP to do small little file system changes for a while but this is the first I have run into this.

Is there some work around for this?
Could I rename the files (not the function, but just replace the offending characters) so that at least I can move them? Can I convert the encoding of the file beforehand? I am not sure where to start. What I am aiming to do is get the file’s name before the move, rename it into something appropriate. So far, I tried str_replace to get all of the ??s that php uses to replace the special characters, but this did not work, I still couldn’t move the file. (the rename function failed)

Well, you can’t rename to a safe name because rename in itself needs a safe name to work in the first place. I don’t know the solution - but probably you could call some native windows commands using exec() for file manipulations - just an idea. Or, have a loot at the last comment in the bug report about creating the COM object.

I don’t know anything about the COM class and can’t quite understand it. (http://us3.php.net/manual/en/class.com.php). It wants me to input a module name, but I have no idea what module to input and what its commands will be once I do. Maybe this is some .NET stuff?

I tried the exec idea you mentioned but then quickly realized I don’t really know much windows scripting :(. Although I ultimately found out how to move files with exec via windows cmds, I could not move and rename in php because php could not read the file name. Since the final output file is based on the name of the original file (it is a concatenation of the folder the file is in and the file’s name) I still couldn’t do this in php as far as I could tell, since any variables containing special characters (aka the original filenames) that I tried to insert into the exec were already corrupt when php read them originally and stored it as a variable. (Which makes sense.) I guess as soon as PHP attempts to store one of the filenames, bad characters will be replaced with ??s so there is no way for PHP to perform operations on them itself.

Someone apparently found a workaround here to run UTF-8 windows commands using an external proxy batch file. If this works then you could issue windows commands like dir, rename, copy, etc. to manipulate your files. Much more complicated than using standard php functions but should be doable.