I need to delete old files with special characters in filenames like space,,
,(
,)
,!
and so on via PHP. Classic unlink($filename)
does not work for these files. How can I transform filenames to filenames which accepts unlink function and filesystem? It's running on a Solaris machine and I don't have another access to it.
4 Answers
How are you constructing the $filename
? unlink should work on any filename with special characters if you do the normal escaping on it. e.g.
for a file with a name of this has, various/wonky !characters in it
, then
$filename = 'this has\, various\/wonky \!characters in it';
unlink($filename);
should work.

- 356,200
- 43
- 426
- 500
-
Filename is output from readdir command, i compare if files in directory is used id database and if not, delete it. I don't escape this filename, is there a way to auto-espace it? I need to add that there can be also cp-1250 characters like "ž ľ č š" and so on... – gadelat Dec 29 '10 at 19:25
-
1Well, if you're dealing with filenames that contain shell metacharacters, then you do need to escape those. Unlink won't know that a `/` in the filename is actually part of the filename and not the directory separator unless you escape it yourself. – Marc B Dec 29 '10 at 19:28
-
The cp-1250 characters shouldn't be a problem, unless for whatever reason PHP and/or your glibc are working on a different codepage/charset at the time. It's possible (but not likely) that one of the accented chars in the "foreign" charset could by chance map to one of the shell metacharacters, like `/` and then you're back to square one. – Marc B Dec 29 '10 at 19:30
-
Solaris filesystems don't allow / in filenames, it's always a directory separator, so there's no reason to escape it. – alanc Dec 31 '10 at 16:46
unlink accepts any valid string and will try to delete the file in that string.
unlink('/home/user1/"hello(!,');
Perhaps you are not properly escaping certain characters.

- 48,414
- 8
- 88
- 101
You can also find all needed files and unlink them using RegexIterator:
<?php
$dir = new RecursiveDirectoryIterator('.');
$iterator = new RecursiveIteratorIterator($dir);
$regex = new RegexIterator($iterator, '/(^.*[\s\.\,\(\)\!]+.*)/', RecursiveRegexIterator::GET_MATCH);
foreach ($regex as $file) {
if (is_file($file[0])) {
print "Unlink file {$file[0]}\n";
unlink($file[0]);
}
}
This code snippet recursively traverse all directories from current ('.') and matches all files by regex '/(^.[\s\,.()!]+.)/', then delete them.

- 406
- 3
- 7
The way I do it in Linux is to use absolute paths, like "rm ./filename" that is dot slash.
You can also use escape charachters. Like "rm \-filename" that is - backspash hyphen.

- 126
- 3