Unlinking files and directories in PHP - php

The following code successfully removes sub directories and the files within them.
However it also removes all files in the directory above what is specified as $dir. This is not desired.
Can anybody see what is wrong with the code?
private function unlinkPubDirectory()
{
$dir = DIR_DOWNLOAD_PUB;
$h1 = opendir($dir);
while ($subdir = readdir($h1)) {
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
#unlink($dir . $subdir . '/' . $file);
}
closedir($h2);
#rmdir($dir . $subdir);
}
closedir($h1);
}

As marked in the comments you should check for '..' as a possible file/directory and omit it. Additionally, check for errors without the '#'-sign.
private function unlinkPubDirectory()
{
$dir = DIR_DOWNLOAD_PUB;
$h1 = opendir($dir);
while ($subdir = readdir($h1)) {
if ($subdir == '..') continue; // don't do anything with '..'
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
unlink($dir . $subdir . '/' . $file);
}
closedir($h2);
rmdir($dir . $subdir);
}
closedir($h1);
}

This will show you what is being deleted
while ($subdir = readdir($h1)) {
$h2 = opendir($dir . $subdir);
while ($file = readdir($h2)) {
echo "<p>will remove file " . ($dir . $subdir . '/' . $file);
}
closedir($h2);
echo "<p>will remove dir " . ($dir . $subdir);
}
HINT: check for . or .. folders and ignore them

Related

Bulk str_replace sub-folder names with PHP

I have a lot of subfolders that have spaces in their names (in this example under main folder TEMP, could be folders "folder A" "folder B has many spaces" etc. I have tried this code to replace all sub folder names spaces with underlines but could someone please tell me why it isn't working?
Cheers.
<?php
$dir = 'https://www.example.com/image/catalog/TEMP';
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($foldername = readdir($dh)) !== false) {
rename($dir.$foldername, str_replace(" ","_",$dir.$foldername));
}
closedir($dh);
}
}
?>
Keep in mind You cannot list directories by URL and rename them.
So please write at least relative path.
For example if script at root of www:
$dir = __DIR__ . DS . 'image/catalog/TEMP';
<?php
const DS = DIRECTORY_SEPARATOR;
$dir = __DIR__ . DS . 'image/catalog/TEMP';
if (!is_dir($dir)) {
echo "\n".$dir." is not directory"."\n";
exit(0);
}
$dh = opendir($dir);
while ($item = readdir($dh)) :
if ($item === '.' || $item === '..') continue;
$current = $dir . DS . $item;
$new = $dir . DS . str_replace(" ", "_", $item);
if ($current === $new) continue; // nothing to rename
rename($current, $new);
echo $current.' => '.$new."\n";
endwhile;
closedir($dh);

Search file in directories and return value

I running this script for search file name inside different directories, the problem it´s don´t show me the return value, only works if use print or echo inside function, i think the problem it´s return value with recursive function
My Code :
function search_file_dir($ruta, $search)
{
$dir = opendir("" . $ruta . "");
while ($file = readdir($dir)) {
if ($file != "." && $file != "..") {
if (is_dir("" . $ruta . "/" . $file . "")) {
$dir_out = "" . $file . "";
search_file_dir("" . $ruta . "/" . $file . "", "" . $search . "");
}
if (is_file("" . $ruta . "/" . $file . "")) {
if (substr($file, 0, -4) == $search) {
$ruta_end = "" . $ruta . "/" . $file . "";
}
}
}
}
closedir($dir);
return $ruta_end;
}
And works calling this
echo search_file_dir("gallery","flower.png")
By this my question because how use return value in this case for show the value if function it´s recursive, the funtions works fine and search all, in all kind of directories but don´t works return
Thank´s in advanced
Best Regards
You are not returning the search result on each recursion.
The function returns $ruta_end when your is_file() condition is true.
But when it is is_dir() there is an empty response because $ruta_end has not been assigned a value.
This makes the function provide a valid response for root dirs (as mentioned by you) but when searching in sub directories the response will be empty.
Basically do this $ruta_end = search_file_dir(...)
function search_file_dir($ruta, $search)
{
$dir = opendir("" . $ruta . "");
while ($file = readdir($dir)) {
if ($file != "." && $file != "..") {
if (is_dir("" . $ruta . "/" . $file . "")) {
$dir_out = "" . $file . "";
$ruta_end = search_file_dir("" . $ruta . "/" . $file . "", "" . $search . "");
}
if (is_file("" . $ruta . "/" . $file . "")) {
## Why are you using a substr -> to remove extension?
## If yes then it will not work on extensions like 'docx` (length more than 3)
## Use pathinfo() instead
## In your question the search term is flower.png so why remove extension in the first place. But I assume that is a typo
if (substr($file, 0, -4) == $search) {
$ruta_end = "" . $ruta . "/" . $file . "";
}
}
}
}
closedir($dir);
return $ruta_end;
}

How to copy the only particular extension file in php?

Hello I am using following code for copy the files from one directory to another directory its worked like a charms This is my code:
<?php
function recurse_copy($src,$dst) {
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
} if(isset($_POST["source"]) && isset($_POST["destination"])){
$src = $_POST["source"];
$dst = $_POST["destination" ];
recurse_copy($src,$dst);
}
?>
now I want to copy only the image files from the source folder.How can i do that?
Getimagesize can help you. It return false on error. File not image is error.
<?php
function recurse_copy($src,$dst) {
$dir = opendir($src);
#mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
/////
if(!getimagesize($src . '/' . $file,$dst . '/' . $file)) continue;
/////
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
} if(isset($_POST["source"]) && isset($_POST["destination"])){
$src = $_POST["source"];
$dst = $_POST["destination" ];
recurse_copy($src,$dst);
}
?>
OR
You just can check file extension:
$ext = end(explode('.',$file));
But it can lie.
I see 2 ways:
You make an array of the possible file extensions, and check end of
$file var for every file.
Or you use exif_imagetype() function along with the Imagetype
contants to determine the file type from the signature. Documentation
is here. However, there is a dependency for this, for details
see the first user contributed note.

How to display all my files by date modified?

I'm new to PHP and i was just wondering if someone could help. I want my code to read files from a directory/sub directory and display all of them by the date they were modified! My code displays only one file, which is the one that I recently changed. So how do I list all the files? I hope this question makes some sense..
<?php
$last_mtimes = array();
function ListFiles($dir) {
if($dh = opendir($dir)) {
$files = Array();
$inner_files = Array();
while($file = readdir($dh)) {
if($file != "." && $file != ".." && $file[0] != '.') {
if(is_dir($dir . "/" . $file)) {
$inner_files = ListFiles($dir . "/" . $file);
if(is_array($inner_files)) $files = array_merge($files, $inner_files);
} else {
array_push($files, $dir . "/" . $file);
$lmtime = filemtime($dir . "/" . $file) ;
$last_mtimes[$lmtime] = $dir . "/" . $file;
}
}
}
krsort($last_mtimes);
closedir($dh);
return ($last_mtimes);
}
}
foreach (ListFiles('folder/folder/') as $key=>$file);
echo array_shift(ListFiles('folder/folder/'));
?>
There is an extra semi colon which makes the loop do nothing:
foreach (ListFiles('folder/folder/') as $key=>$file);
^ remove this

PHP read sub-directories and loop through files how to?

I need to create a loop through all files in subdirectories. Can you please help me struct my code like this:
$main = "MainDirectory";
loop through sub-directories {
loop through filels in each sub-directory {
do something with each file
}
};
Use RecursiveDirectoryIterator in conjunction with RecursiveIteratorIterator.
$di = new RecursiveDirectoryIterator('path/to/directory');
foreach (new RecursiveIteratorIterator($di) as $filename => $file) {
echo $filename . ' - ' . $file->getSize() . ' bytes <br/>';
}
You need to add the path to your recursive call.
function readDirs($path){
$dirHandle = opendir($path);
while($item = readdir($dirHandle)) {
$newPath = $path."/".$item;
if(is_dir($newPath) && $item != '.' && $item != '..') {
echo "Found Folder $newPath<br>";
readDirs($newPath);
}
else{
echo ' Found File or .-dir '.$item.'<br>';
}
}
}
$path = "/";
echo "$path<br>";
readDirs($path);
You probably want to use a recursive function for this, in case your sub directories have sub-sub directories
$main = "MainDirectory";
function readDirs($main){
$dirHandle = opendir($main);
while($file = readdir($dirHandle)){
if(is_dir($main . $file) && $file != '.' && $file != '..'){
readDirs($file);
}
else{
//do stuff
}
}
}
didn't test the code, but this should be close to what you want.
I like glob with it's wildcards :
foreach (glob("*/*.txt") as $filename) {
echo "$filename\n";
}
Details and more complex scenarios.
But if You have a complex folders structure RecursiveDirectoryIterator is definitively the solution.
Come on, first try it yourself!
What you'll need:
scandir()
is_dir()
and of course foreach
http://php.net/manual/en/function.is-dir.php
http://php.net/manual/en/function.scandir.php
Another solution to read with sub-directories and sub-files (set correct foldername):
<?php
$path = realpath('samplefolder/yorfolder');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
echo "$filename <br/>";
}
?>
Minor modification on what John Marty posted, if we can safely eliminate any items that are named . or ..
function readDirs($path){
$dirHandle = opendir($path);
while($item = readdir($dirHandle)) {
$newPath = $path."/".$item;
if (($item == '.') || ($item == '..')) {
continue;
}
if (is_dir($newPath)) {
pretty_echo('Found Folder '.$newPath);
readDirs($newPath);
} else {
pretty_echo('Found File: '.$item);
}
}
}
function pretty_echo($text = '')
{
echo $text;
if (PHP_OS == 'Linux') {
echo "\r\n";
}
else {
echo "</br>";
}
}
<?php
ini_set('max_execution_time', 300); // increase the execution time of the file (in case the number of files or file size is more).
class renameNewFile {
static function copyToNewFolder() { // copies the file from one location to another.
$main = 'C:\xampp\htdocs\practice\demo'; // Source folder (inside this folder subfolders and inside each subfolder files are present.)
$main1 = 'C:\xampp\htdocs\practice\demomainfolder'; // Destination Folder
$dirHandle = opendir($main); // Open the source folder
while ($file = readdir($dirHandle)) { // Read what's there inside the source folder
if (basename($file) != '.' && basename($file) != '..') { // Ignore if the folder name is '.' or '..'
$folderhandle = opendir($main . '\\' . $file); // Open the Sub Folders inside the Main Folder
while ($text = readdir($folderhandle)) {
if (basename($text) != '.' && basename($text) != '..') { // Ignore if the folder name is '.' or '..'
$filepath = $main . '\\' . $file . '\\' . $text;
if (!copy($filepath, $main1 . '\\' . $text)) // Copy the files present inside the subfolders to destination folder
echo "Copy failed";
else {
$fh = fopen($main1 . '\\' . 'log.txt', 'a'); // Write a log file to show the details of files copied.
$text1 = str_replace(' ', '_', $text);
$data = $file . ',' . strtolower($text1) . "\r\n";
fwrite($fh, $data);
echo $text . " is copied <br>";
}
}
}
}
}
}
static function renameNewFileInFolder() { //Renames the files into desired name
$main1 = 'C:\xampp\htdocs\practice\demomainfolder';
$dirHandle = opendir($main1);
while ($file = readdir($dirHandle)) {
if (basename($file) != '.' && basename($file) != '..') {
$filepath = $main1 . '\\' . $file;
$text1 = strtolower($filepath);
rename($filepath, $text1);
$text2 = str_replace(' ', '_', $text1);
if (rename($filepath, $text2))
echo $filepath . " is renamed to " . $text2 . '<br/>';
}
}
}
}
renameNewFile::copyToNewFolder();
renameNewFile::renameNewFileInFolder();
?>
$allFiles = [];
public function dirIterator($dirName)
{
$whatsInsideDir = scandir($dirName);
foreach ($whatsInsideDir as $fileOrDir) {
if (is_dir($fileOrDir)) {
dirIterator($fileOrDir);
}
$allFiles.push($fileOrDir);
}
return $allFiles;
}

Categories