On my way to learning the mkdir(); function in PHP, I have created a folder on my server with a path like so
files/New\\\\
Now, I can not delete this for the life of me...
I found one other post that said I would need to use
rmdir();
and escape the backslashes with more backslashes...
Needless to say, I can not get this to work... I had no idea that PHP added slashes through a post. I know from here forth I should use stripslashes(); but for now, I am stuck with two non deletable folders.
Any ideas guys?
Quick'n'dirty script:
$filename = glob('../files/*');
foreach($filename as $file) {
print "'". $file. "' ";
if(strstr($file,'New')) {
if(is_file($file)) {
unlink($file);
}
}
}
foreach($filename as $file) {
if(strstr($file,'New')) {
r_rmdir($file);
}
}
function r_rmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir") r_rmdir($dir."/".$object); else unlink($dir."/".$object);
}
}
reset($objects);
rmdir($dir);
}
}
1.
This should remove all the folders and files you have created for both directories, just run this script and it should remove them both completely
PHP
rmdir("../files/New\\\\/thumbnail");
rmdir("../files/New\\\\");
$filename = glob('../files/New\\\\\\\\\\\\\\\\/*');
foreach($filename as $file) {
if(is_file($file)) {
unlink($file);
}
}
rmdir("../files/New\\\\\\\\\\\\\\\\/thumbnail");
rmdir("../files/New\\\\\\\\\\\\\\\\");
2.
Have you tried renaming the folder with php? Like, so
PHP
$oldname = '../files/New\\\\';
$newname = '../files/please';
rename($oldname, $newname);
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Does glob() have negation?
I want to delete all files from a directory (could be any number of file extentions) apart from the single index.html in there.
I'm using:
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
unlink($file);
}
But can't for the life of me how to say unlink, if not .html!
Thanks!
Try this here...
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
$pathPart = explode(".",$file);
$fileEx = $pathPart[count($pathPart)-1];
if($fileEx != "html" && $fileEx != "htm"){
unlink($file);
}
}
try
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
if(pathinfo($file, PATHINFO_EXTENSION) != 'html') {
unlink($file);
}
}
if you want to delete other html files also (apart from "index.html"):
$path = "/assets/cache/";
foreach(glob($path ."*.*") as $file) {
if(pathinfo($file, PATHINFO_BASENAME) != 'index.html') {
unlink($file);
}
}
The php function glob has no negation, however PHP can give you the difference between two globs via array_diff:
$all = glob("*.*");
$not = glob("php_errors.log");
var_dump(
$all,
$not,
array_diff($all, $not)
);
See the demo: http://codepad.org/RBFwPUWm
If you do not want to use arrays, I highly suggest to take a look into PHPs directory iterators.
I there a way I can use RegExp or Wildcard searches to quickly delete all files within a folder, and then remove that folder in PHP, WITHOUT using the "exec" command? My server does not give me authorization to use that command. A simple loop of some kind would suffice.
I need something that would accomplish the logic behind the following statement, but obviously, would be valid:
$dir = "/home/dir"
unlink($dir . "/*"); # "*" being a match for all strings
rmdir($dir);
Use glob to find all files matching a pattern.
function recursiveRemoveDirectory($directory)
{
foreach(glob("{$directory}/*") as $file)
{
if(is_dir($file)) {
recursiveRemoveDirectory($file);
} else {
unlink($file);
}
}
rmdir($directory);
}
Use glob() to easily loop through the directory to delete files then you can remove the directory.
foreach (glob($dir."/*.*") as $filename) {
if (is_file($filename)) {
unlink($filename);
}
}
rmdir($dir);
The glob() function does what you're looking for. If you're on PHP 5.3+ you could do something like this:
$dir = ...
array_walk(glob($dir . '/*'), function ($fn) {
if (is_file($fn))
unlink($fn);
});
unlink($dir);
A simple and effective way of deleting all files and folders recursively with Standard PHP Library, to be specific, RecursiveIteratorIterator and RecursiveDirectoryIterator. The point is in RecursiveIteratorIterator::CHILD_FIRST flag, iterator will loop through files first, and directory at the end, so once the directory is empty it is safe to use rmdir().
foreach( new RecursiveIteratorIterator(
new RecursiveDirectoryIterator( 'folder', FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS ),
RecursiveIteratorIterator::CHILD_FIRST ) as $value ) {
$value->isFile() ? unlink( $value ) : rmdir( $value );
}
rmdir( 'folder' );
Try easy way:
$dir = "/home/dir";
array_map('unlink', glob($dir."/*"));
rmdir($dir);
In Function for remove dir:
function unlinkr($dir, $pattern = "*") {
// find all files and folders matching pattern
$files = glob($dir . "/$pattern");
//interate thorugh the files and folders
foreach($files as $file){
//if it is a directory then re-call unlinkr function to delete files inside this directory
if (is_dir($file) and !in_array($file, array('..', '.'))) {
unlinkr($file, $pattern);
//remove the directory itself
rmdir($file);
} else if(is_file($file) and ($file != __FILE__)) {
// make sure you don't delete the current script
unlink($file);
}
}
rmdir($dir);
}
//call following way:
unlinkr("/home/dir");
You can use the Symfony Filesystem component, to avoid re-inventing the wheel, so you can do
use Symfony\Component\Filesystem\Filesystem;
$filesystem = new Filesystem();
if ($filesystem->exists('/home/dir')) {
$filesystem->remove('/home/dir');
}
If you prefer to manage the code yourself, here's the Symfony codebase for the relevant methods
class MyFilesystem
{
private function toIterator($files)
{
if (!$files instanceof \Traversable) {
$files = new \ArrayObject(is_array($files) ? $files : array($files));
}
return $files;
}
public function remove($files)
{
$files = iterator_to_array($this->toIterator($files));
$files = array_reverse($files);
foreach ($files as $file) {
if (!file_exists($file) && !is_link($file)) {
continue;
}
if (is_dir($file) && !is_link($file)) {
$this->remove(new \FilesystemIterator($file));
if (true !== #rmdir($file)) {
throw new \Exception(sprintf('Failed to remove directory "%s".', $file), 0, null, $file);
}
} else {
// https://bugs.php.net/bug.php?id=52176
if ('\\' === DIRECTORY_SEPARATOR && is_dir($file)) {
if (true !== #rmdir($file)) {
throw new \Exception(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
}
} else {
if (true !== #unlink($file)) {
throw new \Exception(sprintf('Failed to remove file "%s".', $file), 0, null, $file);
}
}
}
}
}
public function exists($files)
{
foreach ($this->toIterator($files) as $file) {
if (!file_exists($file)) {
return false;
}
}
return true;
}
}
One way of doing it would be:
function unlinker($file)
{
unlink($file);
}
$files = glob('*.*');
array_walk($files,'unlinker');
rmdir($dir);
for removing all the files you can remove the directory and make again.. with a simple line of code
<?php
$dir = '/home/files/';
rmdir($dir);
mkdir($dir);
?>
I have a script that gets a string from a config file and based on that string grabs the file names of a folder.
I now only need the iso files. Not sure if the best way is to check for the .iso string or is there another method?
<?php
// Grab the contents of the "current.conf" file, removing any linebreaks.
$dirPath = trim(file_get_contents('current.conf')).'/';
$fileList = scandir($dirPath);
if(is_array($fileList)) {
foreach($fileList as $file) {
//could replace the below if statement to only proceed if the .iso string is present. But I am worried there could be issues with this.
if ($file != "." and $file != ".." and $file != "index.php")
{
echo "<br/><a href='". $dirPath.$file."'>" .$file."</a>\n";
}
}
}
else echo $dirPath.' cound not be scanned.';
?>
If you only need the files with an extension of .iso, then why not use:
glob($dirPath.'/*.iso');
rather than scandir()
try this:
if(is_array($fileList)) {
foreach($fileList as $file) {
$fileSplode = explode('.',$file); //split by '.'
//this means that u now have an array with the 1st element being the
//filename and the 2nd being the extension
echo (isset($fileSplode[1]) && $fileSplode[1]=='iso')?
"<br/><a href='". $dirPath.$file."'>" .$file."</a>\n":'');
}
}
If you want it in an OOP style you could use:
<?php
foreach (new DirectoryIterator($dirPath) as $fileInfo) {
if($fileInfo->getExtension() == 'iso') {
// do something with it
}
}
?>
For example I had a folder called `Temp' and I wanted to delete or flush all files from this folder using PHP. Could I do this?
$files = glob('path/to/temp/*'); // get all file names
foreach($files as $file){ // iterate files
if(is_file($file)) {
unlink($file); // delete file
}
}
If you want to remove 'hidden' files like .htaccess, you have to use
$files = glob('path/to/temp/{,.}*', GLOB_BRACE);
If you want to delete everything from folder (including subfolders) use this combination of array_map, unlink and glob:
array_map( 'unlink', array_filter((array) glob("path/to/temp/*") ) );
This call can also handle empty directories ( thanks for the tip, #mojuba!)
Here is a more modern approach using the Standard PHP Library (SPL).
$dir = "path/to/directory";
if(file_exists($dir)){
$di = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$ri = new RecursiveIteratorIterator($di, RecursiveIteratorIterator::CHILD_FIRST);
foreach ( $ri as $file ) {
$file->isDir() ? rmdir($file) : unlink($file);
}
}
foreach (new DirectoryIterator('/path/to/directory') as $fileInfo) {
if(!$fileInfo->isDot()) {
unlink($fileInfo->getPathname());
}
}
This code from http://php.net/unlink:
/**
* Delete a file or recursively delete a directory
*
* #param string $str Path to file or directory
*/
function recursiveDelete($str) {
if (is_file($str)) {
return #unlink($str);
}
elseif (is_dir($str)) {
$scan = glob(rtrim($str,'/').'/*');
foreach($scan as $index=>$path) {
recursiveDelete($path);
}
return #rmdir($str);
}
}
$dir = 'your/directory/';
foreach(glob($dir.'*.*') as $v){
unlink($v);
}
Assuming you have a folder with A LOT of files reading them all and then deleting in two steps is not that performing.
I believe the most performing way to delete files is to just use a system command.
For example on linux I use :
exec('rm -f '. $absolutePathToFolder .'*');
Or this if you want recursive deletion without the need to write a recursive function
exec('rm -f -r '. $absolutePathToFolder .'*');
the same exact commands exists for any OS supported by PHP.
Keep in mind this is a PERFORMING way of deleting files. $absolutePathToFolder MUST be checked and secured before running this code and permissions must be granted.
See readdir and unlink.
<?php
if ($handle = opendir('/path/to/files'))
{
echo "Directory handle: $handle\n";
echo "Files:\n";
while (false !== ($file = readdir($handle)))
{
if( is_file($file) )
{
unlink($file);
}
}
closedir($handle);
}
?>
The simple and best way to delete all files from a folder in PHP
$files = glob('my_folder/*'); //get all file names
foreach($files as $file){
if(is_file($file))
unlink($file); //delete file
}
Got this source code from here - http://www.codexworld.com/delete-all-files-from-folder-using-php/
unlinkr function recursively deletes all the folders and files in given path by making sure it doesn't delete the script itself.
function unlinkr($dir, $pattern = "*") {
// find all files and folders matching pattern
$files = glob($dir . "/$pattern");
//interate thorugh the files and folders
foreach($files as $file){
//if it is a directory then re-call unlinkr function to delete files inside this directory
if (is_dir($file) and !in_array($file, array('..', '.'))) {
echo "<p>opening directory $file </p>";
unlinkr($file, $pattern);
//remove the directory itself
echo "<p> deleting directory $file </p>";
rmdir($file);
} else if(is_file($file) and ($file != __FILE__)) {
// make sure you don't delete the current script
echo "<p>deleting file $file </p>";
unlink($file);
}
}
}
if you want to delete all files and folders where you place this script then call it as following
//get current working directory
$dir = getcwd();
unlinkr($dir);
if you want to just delete just php files then call it as following
unlinkr($dir, "*.php");
you can use any other path to delete the files as well
unlinkr("/home/user/temp");
This will delete all files in home/user/temp directory.
Another solution:
This Class delete all files, subdirectories and files in the sub directories.
class Your_Class_Name {
/**
* #see http://php.net/manual/de/function.array-map.php
* #see http://www.php.net/manual/en/function.rmdir.php
* #see http://www.php.net/manual/en/function.glob.php
* #see http://php.net/manual/de/function.unlink.php
* #param string $path
*/
public function delete($path) {
if (is_dir($path)) {
array_map(function($value) {
$this->delete($value);
rmdir($value);
},glob($path . '/*', GLOB_ONLYDIR));
array_map('unlink', glob($path."/*"));
}
}
}
Posted a general purpose file and folder handling class for copy, move, delete, calculate size, etc., that can handle a single file or a set of folders.
https://gist.github.com/4689551
To use:
To copy (or move) a single file or a set of folders/files:
$files = new Files();
$results = $files->copyOrMove('source/folder/optional-file', 'target/path', 'target-file-name-for-single-file.only', 'copy');
Delete a single file or all files and folders in a path:
$files = new Files();
$results = $files->delete('source/folder/optional-file.name');
Calculate the size of a single file or a set of files in a set of folders:
$files = new Files();
$results = $files->calculateSize('source/folder/optional-file.name');
<?
//delete all files from folder & sub folders
function listFolderFiles($dir)
{
$ffs = scandir($dir);
echo '<ol>';
foreach ($ffs as $ff) {
if ($ff != '.' && $ff != '..') {
if (file_exists("$dir/$ff")) {
unlink("$dir/$ff");
}
echo '<li>' . $ff;
if (is_dir($dir . '/' . $ff)) {
listFolderFiles($dir . '/' . $ff);
}
echo '</li>';
}
}
echo '</ol>';
}
$arr = array(
"folder1",
"folder2"
);
for ($x = 0; $x < count($arr); $x++) {
$mm = $arr[$x];
listFolderFiles($mm);
}
//end
?>
For me, the solution with readdir was best and worked like a charm. With glob, the function was failing with some scenarios.
// Remove a directory recursively
function removeDirectory($dirPath) {
if (! is_dir($dirPath)) {
return false;
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
if ($handle = opendir($dirPath)) {
while (false !== ($sub = readdir($handle))) {
if ($sub != "." && $sub != ".." && $sub != "Thumb.db") {
$file = $dirPath . $sub;
if (is_dir($file)) {
removeDirectory($file);
} else {
unlink($file);
}
}
}
closedir($handle);
}
rmdir($dirPath);
}
public static function recursiveDelete($dir)
{
foreach (new \DirectoryIterator($dir) as $fileInfo) {
if (!$fileInfo->isDot()) {
if ($fileInfo->isDir()) {
recursiveDelete($fileInfo->getPathname());
} else {
unlink($fileInfo->getPathname());
}
}
}
rmdir($dir);
}
I've built a really simple package called "Pusheh". Using it, you can clear a directory or remove a directory completely (Github link). It's available on Packagist, also.
For instance, if you want to clear Temp directory, you can do:
Pusheh::clearDir("Temp");
// Or you can remove the directory completely
Pusheh::removeDirRecursively("Temp");
If you're interested, see the wiki.
I updated the answer of #Stichoza to remove files through subfolders.
function glob_recursive($pattern, $flags = 0) {
$fileList = glob($pattern, $flags);
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
$subPattern = $dir.'/'.basename($pattern);
$subFileList = glob_recursive($subPattern, $flags);
$fileList = array_merge($fileList, $subFileList);
}
return $fileList;
}
function glob_recursive_unlink($pattern, $flags = 0) {
array_map('unlink', glob_recursive($pattern, $flags));
}
This is a simple way and good solution. try this code.
array_map('unlink', array_filter((array) array_merge(glob("folder_name/*"))));
when moving one file from one location to another i use
rename('path/filename', 'newpath/filename');
how do you move all files in a folder to another folder? tried this one without result:
rename('path/*', 'newpath/*');
A slightly verbose solution:
// Get array of all source files
$files = scandir("source");
// Identify directories
$source = "source/";
$destination = "destination/";
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// If we copied this successfully, mark it for deletion
if (copy($source.$file, $destination.$file)) {
$delete[] = $source.$file;
}
}
// Delete all successfully-copied files
foreach ($delete as $file) {
unlink($file);
}
Please try this solution, it's tested successfully ::
<?php
$files = scandir("f1");
$oldfolder = "f1/";
$newfolder = "f2/";
foreach($files as $fname) {
if($fname != '.' && $fname != '..') {
rename($oldfolder.$fname, $newfolder.$fname);
}
}
?>
An alternate using rename() and with some error checking:
$srcDir = 'dir1';
$destDir = 'dir2';
if (file_exists($destDir)) {
if (is_dir($destDir)) {
if (is_writable($destDir)) {
if ($handle = opendir($srcDir)) {
while (false !== ($file = readdir($handle))) {
if (is_file($srcDir . '/' . $file)) {
rename($srcDir . '/' . $file, $destDir . '/' . $file);
}
}
closedir($handle);
} else {
echo "$srcDir could not be opened.\n";
}
} else {
echo "$destDir is not writable!\n";
}
} else {
echo "$destDir is not a directory!\n";
}
} else {
echo "$destDir does not exist\n";
}
tried this one?:
<?php
$oldfolderpath = "old/folder";
$newfolderpath = "new/folder";
rename($oldfolderpath,$newfolderpath);
?>
So I tried to use the rename() function as described and I kept getting the error back that there was no such file or directory. I placed the code within an if else statement in order to ensure that I really did have the directories created. It looked like this:
$tempDir = '/home/site/images/tmp/';
$permanentDir = '/home/site/images/' . $claimid; // this was stored above
mkdir($permanentDir,0775);
if(is_dir($permanentDir)){
echo $permanentDir . ' is a directory';
if(is_dir($tempDir)){
echo $tempDir . ' is a directory';
}else{
echo $tempDir . ' is not a directory';
}
}else{
echo $permanentDir . ' is not a directory';
}
rename($tempDir . "*", $permanentDir);
So when I ran the code again, it spit out that both paths were directories. I was stumped. I talked with a coworker and he suggested, "Why not just rename the temp directory to the new directory, since you want to move all the files anyway?"
Turns out, this is what I ended up doing. I gave up trying to use the wildcard with the rename() function and instead just use the rename() to rename the temp directory to the permanent one.
so it looks like this.
$tempDir = '/home/site/images/tmp/';
$permanentDir = '/home/site/images/' . $claimid; // this was stored above
mkdir($permanentDir,0775);
rename($tempDir, $permanentDir);
This worked beautifully for my purposes since I don't need the old tmp directory to remain there after the files have been uploaded and "moved".
Hope this helps. If anyone knows why the wildcard doesn't work in the rename() function and why I was getting the error stating above, please, let me know.
Move or copy the way I use it
function copyfiles($source_folder, $target_folder, $move=false) {
$source_folder=trim($source_folder, '/').'/';
$target_folder=trim($target_folder, '/').'/';
$files = scandir($source_folder);
foreach($files as $file) {
if($file != '.' && $file != '..') {
if ($move) {
rename($source_folder.$file, $target_folder.$file);
} else {
copy($source_folder.$file, $target_folder.$file);
}
}
}
}
function movefiles($source_folder, $target_folder) {
copyfiles($source_folder, $target_folder, $move=true);
}
try this:
rename('path/*', 'newpath/');
I do not see a point in having an asterisk in the destination
If the target directory doesn't exist, you'll need to create it first:
mkdir('newpath');
rename('path/*', 'newpath/');
As a side note; when you copy files to another folder, their last changed time becomes current timestamp. So you should touch() the new files.
... (some codes for directory looping) ...
if (copy($source.$file, $destination.$file)) {
$delete[] = $source.$file;
$filetimestamp = filemtime($source.$file);
touch($destination.$file,$filetimestamp);
}
... (some codes) ...
Not sure if this helps anyone or not, but thought I'd post anyway. Had a challenge where I has heaps of movies I'd purchased and downloaded through various online stores all stored in one folder, but all in their own subfolders and all with different naming conventions. I wanted to move all of them into the parent folder and rename them all to look pretty. all of the subfolders I'd managed to rename with a bulk renaming tool and conditional name formatting. the subfolders had other files in them i didn't want. so i wrote the following php script to, 1. rename/move all files with extension mp4 to their parent directory while giving them the same name as their containing folder, 2. delete contents of subfolders and look for directories inside them to empty and then rmdir, 3. rmdir the subfolders.
$handle = opendir("D:/Movies/");
while ($file = readdir($handle)) {
if ($file != "." && $file != ".." && is_dir($file)) {
$newhandle = opendir("D:/Movies/".$file);
while($newfile = readdir($newhandle)) {
if ($newfile != "." && $newfile != ".." && is_file("D:/Movies/".$file."/".$newfile)) {
$parts = explode(".",$newfile);
if (end($parts) == "mp4") {
if (!file_exists("D:/Movies/".$file.".mp4")) {
rename("D:/Movies/".$file."/".$newfile,"D:/Movies/".$file.".mp4");
}
else {
unlink("D:/Movies/".$file."/".$newfile);
}
}
else { unlink("D:/Movies/".$file."/".$newfile); }
}
else if ($newfile != "." && $newfile != ".." && is_dir("D:/Movies/".$file."/".$newfile)) {
$dirhandle = opendir("D:/Movies/".$file."/".$newfile);
while ($dirfile = readdir($dirhandle)){
if ($dirfile != "." && $dirfile != ".."){
unlink("D:/Movies/".$file."/".$newfile."/".$dirfile);
}
}
rmdir("D:/Movies/".$file."/".$newfile);
}
}
unlink("D:/Movies/".$file);
}
}
i move all my .json files from root folder to json folder with this
foreach (glob("*.json") as $filename) {
rename($filename,"json/".$filename);
}
pd: someone 2020?