198

How do I delete a file from my server with PHP if the file is in another directory?

Here is my page layout:

  • projects/backend/removeProjectData.php (this file deletes all my entries for the database and should also delete the related file)
  • public_files/22.pdf (the place where the file is located.)

I'm using the unlink function:

unlink('../../public_files/' . $fileName);

But this always gives me an error that the file does not exist. Any ideas?

reformed
  • 4,505
  • 11
  • 62
  • 88
Ken
  • 2,654
  • 3
  • 26
  • 29
  • 2
    Use absolute path – Pavunkumar Mar 03 '10 at 13:09
  • 1
    if you dont check using real path, you are likely to get the "." and ".." non-files too, causing file does not exist errors – DrogoNevets Feb 07 '13 at 17:00
  • 1
    But beware, this might not really delete your file if your file has multiple file names / symlinks ! See this thread for more info: http://stackoverflow.com/q/17548906/1114320 – Sliq Jul 19 '13 at 09:08

6 Answers6

243

The following should help

  • realpath — Returns canonicalized absolute pathname
  • is_writable — Tells whether the filename is writable
  • unlink — Deletes a file

Run your filepath through realpath, then check if the returned path is writable and if so, unlink it.

Gordon
  • 312,688
  • 75
  • 539
  • 559
  • 7
    I wonder how w3shools is doing this? http://www.w3schools.com/php/func_filesystem_delete.asp – Fr0zenFyr Aug 28 '15 at 19:35
  • 4
    @Gordon i am sorry.. i used the term wrong which makes a big difference .. i agree it was idiotic.. but what i tried to mean is a coding example would be more helpful .. if i need to visit three other links to understand your reply is it very helpful ? ..sorry again for the wrong word.. i am not from english speaking country ... though it can not be an excuse ... – RbG Sep 13 '15 at 14:22
  • 14
    @RitabrataGautam "if i need to visit three other links to understand your reply is it very helpful?" - Yes, it is. Because after going to the links you will have understood how it works. If I just give you the codes, you will not understand but just copy and paste. What did you learn then? Nothing. Besides, the code for that is *very* trivial. – Gordon Sep 13 '15 at 14:29
  • 1
    @Gordon .. i agree .. your views demand respect .. you earned it #185K .. just two quick questions... 1> if i consider your reply as complete then why many moderators here say that you should provide some code also... not just links ( it cause many down-votes) ... 2> wouldn't it be better if u put some code . now who has learning tendency they will surely visit those links and who doesn't have that they will again go to google to get a ready code . – RbG Sep 13 '15 at 14:41
  • @RitabrataGautam this is a programming site, so providing code *is* helpful most of the time. But the code for this particular question is so easy and trivial that I decided not to post the code but just tell "what" to do. There is instructions in the answer. It tells you what to do with the linked functions. Not "how". Any self-respecting developer worth his or her 2c will be able to figure out the "how" from my answer, e.g. they will be able to write the code themselves. – Gordon Sep 13 '15 at 14:46
  • why not use is_exists? – Reign.85 Apr 25 '16 at 12:47
  • @Reign.85 do you mean `file_exists`? The `is_writable` function does that implicitly and in addition will tell you whether you may delete the file. – Gordon Apr 25 '16 at 12:55
  • 2
    the answer seemed straight forward enough to me: but the code example you wanted: $path = realpath('../../public_files/' . $fileName); if(is_writable($path)){unlink($path);} – me_ Feb 09 '17 at 07:14
  • What does canonicalized mean? My translater could not find a suitable term :) – utdev Mar 08 '17 at 10:51
  • @utdev there is a german language version of the PHP Manual ;) It basically means "eindeutig" hier. – Gordon Mar 08 '17 at 10:54
  • 1
    What is `is_writeable` for? `unlink` returns `false` on failure. – Sui Dream Apr 22 '20 at 08:36
  • @SuiDream to avoid an `E_WARNING` level error to be generated on failure. – Gordon Apr 23 '20 at 06:36
121
$files = [
    './first.jpg',
    './second.jpg',
    './third.jpg'
];

foreach ($files as $file) {
    if (file_exists($file)) {
        unlink($file);
    } else {
        // File not found.
    }
}
Joshua
  • 5,032
  • 2
  • 29
  • 45
UbiQue
  • 1,521
  • 1
  • 12
  • 10
  • 13
    up-voted for using the `file_exists` function. Otherwise you're gonna get an error if the file doesn't exist. – Mahdi Jan 06 '15 at 13:40
18

Check your permissions first of all on the file, to make sure you can a) see it from your script, and b) are able to delete it.

You can also use a path calculated from the directory you're currently running the script in, eg:

unlink(dirname(__FILE__) . "/../../public_files/" . $filename);

(in PHP 5.3 I believe you can use the __DIR__ constant instead of dirname() but I've not used it myself yet)

richsage
  • 26,912
  • 8
  • 58
  • 65
  • I checked the permissions and I wasn't able to see the file at first but now everything works thanks to the realpath. thanks for the advice – Ken Mar 03 '10 at 13:22
8

You can delete the file using

unlink($Your_file_path);

but if you are deleting a file from it's http path then this unlink is not work proper. You have to give a file path correct.

always-a-learner
  • 3,671
  • 10
  • 41
  • 81
5

AIO solution, handles everything, It's not my work but I just improved myself. Enjoy!

/**
 * Unlink a file, which handles symlinks.
 * @see https://github.com/luyadev/luya/blob/master/core/helpers/FileHelper.php
 * @param string $filename The file path to the file to delete.
 * @return boolean Whether the file has been removed or not.
 */
function unlinkFile ( $filename ) {
    // try to force symlinks
    if ( is_link ($filename) ) {
        $sym = @readlink ($filename);
        if ( $sym ) {
            return is_writable ($filename) && @unlink ($filename);
        }
    }

    // try to use real path
    if ( realpath ($filename) && realpath ($filename) !== $filename ) {
        return is_writable ($filename) && @unlink (realpath ($filename));
    }

    // default unlink
    return is_writable ($filename) && @unlink ($filename);
}
Junaid Atari
  • 533
  • 7
  • 17
1

I know this question is a bit old, but this is something simple that works for me very well to delete images off my project I'm working on.

unlink(dirname(__FILE__) . "/img/tasks/" . 'image.jpg');

The dirname(__FILE__) section prints out the base path to your project. The /img/tasks/ are two folders down from my base path. And finally, there's my image I want to delete which you can make into anything you need to.

With this I have not had any problem getting to my files on my server and deleting them.

abetwothree
  • 575
  • 2
  • 8
  • 28