I want to delete all files in a folder except files containing:
Specific file names
Specific file extensions
The following code succeeds in the above first point, but not the second point.
function deletefiles()
{
$path = 'files/';
$filesToKeep = array(
$path."example.jpg",
$path."123.png",
$path."*.mkv"
);
$dirList = glob($path.'*');
foreach ($dirList as $file) {
if (! in_array($file, $filesToKeep)) {
if (is_dir($file)) {
rmdir($file);
} else {
unlink($file);
}//END IF
}//END IF
}//END FOREACH LOOP
}
How can I achieve both conditions?
You need to change a bit your function:
<?php
function deletefiles()
{
$path = 'files/';
$filesToKeep = array(
$path . "example.jpg",
$path . "123.png",
);
$extensionsToKeep = array(
"mkv"
);
$dirList = glob($path . '*');
foreach ($dirList as $file) {
if (!in_array($file, $filesToKeep)) {
if (is_dir($file)) {
rmdir($file);
} else {
$fileExtArr = explode('.', $file);
$fileExt = $fileExtArr[count($fileExtArr)-1];
if(!in_array($fileExt, $extensionsToKeep)){
unlink($file);
}
}//END IF
}//END IF
}
}
Related
I've tried several ways to include a PDF file using PHP on Linux, it works normally on Windows, but not on Linux.
I have several directories with accents and I need to include PDF files that are inside the directories.
I pass the name of the PDF files and include the PDF.
My problem is with the encoding and accentuation of the folders. The files doesn't have accents, only the folders.
Examples of folders / files:
files/ño/hash1.pdf
files/nó/hash2.pdf
files/ção/hash.pdf
function getFileInContents($dir, $filename)
{
$files = scandir($dir);
foreach ($files as $key => $value) {
$path = realpath($dir . '/' . $value);
if (!is_dir($path)) {
if ($filename == $value) {
return $path;
}
} elseif ($value != "." && $value != "..") {
getFileInContents($path, $filename);
}
}
return null;
}
if (!isset($_GET['f'])) {
echo 'File not found';
exit;
}
$local = 'files/';
$path = getFileInContents($local, $_GET['f']);
if (!$path) {
echo 'File not found';
exit;
}
$mime = mime_content_type($path);
header('Content-Type: ' . $mime);
include_once($path);
My answer adds on and expounds on the one offered up by #James, because you have additional issues:
As pointed out in the comment made by #Olivier, you should be using readfile() instead of include.
You should not include the final '/' in your declaration of $local since you will be concatenating a '/' to the passed $dir argument in function getFileInContents.
Presumably function getFileInContents is intended to recursively search subdirectories, but it is not doing this correctly; it only is searching the first subdirectory it finds and if the sought file is not present in that subdirectory it returns with a "not found" condition and never searches any other subdirectories that might be present in the directory.
function getFileInContents($dir, $filename)
{
$files = scandir($dir);
foreach ($files as $key => $value) {
$path = realpath($dir . '/' . $value);
if (!is_dir($path)) {
if ($filename == $value) {
return $path;
}
} elseif ($value != "." && $value != "..") {
$new_path = getFileInContents($path, $filename);
if ($new_path) {
return $new_path;
}
}
}
return null;
}
if (!isset($_GET['f'])) {
echo 'File not found';
exit;
}
$local = 'files';
$path = getFileInContents($local, $_GET['f']);
if (!$path) {
echo 'File not found';
exit;
}
$mime = mime_content_type($path);
header('Content-Type: ' . $mime);
readfile($path);
I don't think the problem is anything to do with the folder names. I think the problem is that your recursive function is not actually returning the value when it finds the file.
When you call getFileInContents($path, $filename); you then need to return the value, if it's not null, to break the loop.
function getFileInContents($dir, $filename)
{
$files = scandir($dir);
foreach ($files as $key => $value) {
$path = realpath($dir . '/' . $value);
if (!is_dir($path)) {
if ($filename == $value) {
return $path;
}
} elseif ($value != "." && $value != "..") {
$testValue = getFileInContents($path, $filename);
if ($testValue!=null){
return $testValue;
}
}
}
return null;
}
hi all I have made a function
function getDirContents($dir, &$results = array()){
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if(!is_dir($path)) {
$results[] = $path;
} else if(is_dir($path) && $value != "." && $value != "..") {
getDirContents($path, $results);
$results[] = $path;
}
}
return $results;
}
and I am calling it in like
$value = $this->getDirContents("/var/www/staging/public/files/rgerger");
way from my controller by I am uable to get the full details of the folder I mean the directories and the subdirectories with all contents ..
scandir is on only giving the folder under the target folder which is only scaned but this is not giving me the content of the child folder upto the end.
You need to assign the result of the recursive method call back to the caller.
My (untested) example
function getDirectoryContents($dir)
{
$files = [];
if (is_dir($dir)) {
foreach(scandir($dir) as $key => $fileName) {
$filePath = realpath($dir . DIRECTORY_SEPARATOR . $fileName);
if ($fileName == '.' || $fileName == '..') {
continue;
}
if (is_dir($filePath)) {
$files[] = getDirectoryContents($filePath);
} else {
$files[] = $fileName;
}
}
}
return $files;
}
As per my comment, you can also use the SPL RecursiveDirectoryIterator which is PHP's inbuilt OOP solution for iterating the file system.
i want to list all directory, sub-directory and files using php.
i have tried following code. it returns all the directory, sub directory and files but it's not showing in correct order.
for ex:default order is 1dir, 2dir, 7dir, 8dir while in browser it shows 1dir, 8dir, 7dir, 2dir which is not correct.
code:
function createDir($path = '.')
{
if ($handle = opendir($path))
{
echo "<ul>";
while (false !== ($file = readdir($handle)))
{
if (is_dir($path.$file) && $file != '.' && $file !='..') {
printSubDir($file, $path);
}
else if ($file != '.' && $file !='..'){
$allowed = array('pdf','doc','docx','xls','xlsx','jpg','png','gif','mp4','avi','3gp','flv','mov','PDF','DOC','DOCX','XLS','XLSX','JPG','PNG','GIF','MP4','AVI','3GP','FLV','MOV','html','HTML','css','CSS','js','JS');
$ext = pathinfo($file, PATHINFO_EXTENSION);
if(in_array($ext,$allowed) ) {
$queue[] = $file;
}
}
}
printQueue($queue, $path);
echo "</ul>";
}
}
function printQueue($queue, $path)
{
sort($queue);
foreach ($queue as $file)
{
//printFile($file, $path);
}
}
function printFile($file, $path) {
echo "<li><a href=\"".$path.$file."\" target='_blank'>$file</a></li>";
}
function printSubDir($dir, $path)
{
echo "<li><span class=\"toggle\">$dir</span>";
createDir($path.$dir."/");
echo "</li>";
}
createDir($path);
?>
need help to fix the code and display the direcotry , subdirectory and files in correct order.
I'm having the same problem during listing a directory files. But I have used DirectoryLister
This code is very useful. You can list out your files easily.
You can implement it by following steps.
Download and extract Directory Lister
Copy resources/default.config.php to resources/config.php
Upload index.php and the resources folder to the folder you want listed
Upload additional files to the same directory as index.php
I hope this might help you
You can start by looping the array and printing each directory:
public function dirtree($dir, $regex='', $ignoreEmpty=false) {
if (!$dir instanceof DirectoryIterator) {
$dir = new DirectoryIterator((string)$dir);
}
$dirs = array();
$files = array();
foreach ($dir as $node) {
if ($node->isDir() && !$node->isDot()) {
// print_r($node);
$tree = dirtree($node->getPathname(), $ignoreEmpty);
// print"<pre>";print_r($tree);
if (!$ignoreEmpty || count($tree)) {
$dirs[$node->getFilename()] = $tree;
}
} elseif ($node->isFile()) {
$name = $node->getFilename();
//if ('' == $regex || preg_match($regex, $name)) {
$files[] = $name;
}
}
asort($dirs);
sort($files);
return array_merge($files, $dirs);
}
Use like this:
$fileslist = dirtree('root');
echo "<pre style='font-size:15px'>";
print_r($fileslist);
I was asked to create a cron job that deletes all files and folders from a folder (recursive)
excluding some file extensions.
I have this code (which I found on the web):
function rrmdir($dir) {
$structure = glob(rtrim($dir, "/").'/*');
if (is_array($structure)) {
foreach($structure as $file) {
if (is_dir($file)) rrmdir($file);
elseif (is_file($file)) unlink($file);
}
}
rmdir($dir);
}
Which will remove ANYTHING from the folder specified,
but as said, I need to add exception to in (all '.php' files should not be remove).
Please assume the following structure for folder:
FOLDER1
FOLDER2
FOLDER3
FILE1.ZIP
FILE2.ZIP
DONOTDELETE1.PHP
DONOTDELETE2.PHP
So, everything should be deleted, except the php files
Can anyone help me with this?
this is modified function try with this. this will delete all file except *.php OR *.PHP
files
function rrmdir($dir) {
$structure = glob(rtrim($dir, "/").'/*');
$rm_dir_flag = true;
if (is_array($structure))
{
foreach($structure as $file)
{
if (is_dir($file))
{
rrmdir($file);
}
else if(is_file($file))
{
$ext = substr($file, -4);
if($ext==".php" || $ext==".PHP")
{
$rm_dir_flag = false;
}
else
{
unlink($file);
}
}
}
}
if($rm_dir_flag)
{
rmdir($dir);
}
}
UPDATE 2:
if you want to protect file with particuar extension you can do this
rrmdir($your_directory, ".php");
//or
rrmdir($your_directory, ".pdf");
//or
rrmdir($your_directory, ".jpeg");
function rrmdir($dir, $protect_extension) {
if(!is_dir($dir))
{
return;
}
$len = strlen($protect_extension)*(-1);
$structure = glob(rtrim($dir, "/").'/*');
$rm_dir_flag = true;
if (is_array($structure))
{
foreach($structure as $file)
{
if (is_dir($file))
{
rrmdir($file, $protect_extension);
}
else if(is_file($file))
{
$ext = substr($file, $len);
if($ext==$protect_extension || $ext==strtoupper($protect_extension))
{
$rm_dir_flag = false;
}
else
{
unlink($file);
}
}
}
}
if($rm_dir_flag)
{
rmdir($dir);
}
}
Can you try this, Added if($ext!='php'){
function rrmdir($dir) {
$structure = glob(rtrim($dir, "/").'/*');
if (is_array($structure)) {
foreach($structure as $file) {
if (is_dir($file)){
rrmdir($file);
}elseif(is_file($file)){
$info = pathinfo($file);
$ext = strtolower($info['extension']);
if($ext!='php'){
unlink($file);
}
}
}
}
rmdir($dir);
}
In my server I have folders and sub-directory
I want to call a flatten methode to a directory to move every files at the same level and remove all empty folders
Here is what i've done so far:
public function flattenDir($dir, $destination=null) {
$files = $this->find($dir . '/*');
foreach ($files as $file) {
if(!$destination){
$destination = $dir . '/' . basename($file);
}
if (!$this->isDirectory($file)) {
$this->move($file, $destination);
}else{
$this->flattenDir($file, $destination);
}
}
foreach ($files as $file) {
$localdir = dirname($file);
if ($this->isDirectory($localdir) && $this->isEmptyDirectory($localdir) && ($localdir != $dir)) {
$this->remove($localdir);
}
}
}
public function find($pattern, $flags = 0) {
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern) . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
$files = array_merge($files, $this->find($dir . '/' . basename($pattern), $flags));
}
return $files;
}
This code dont show any error on run, but the resukt is not as expected.
For exemple if I have /folder1/folder2/file I want to have /folder2/file as a result but here the folders still like they where ...
I finally make my code works, I post it here in case it help someone
I simplified it to make it more efficient. By the way this function is part of a filemanager classe I made, so I use function of my own class, but you can simply replace $this->move($file, $destination); by move($file, $destination);
public function flattenDir($dir, $destination = null) {
$files = $this->find($dir . '/*');
foreach ($files as $file) {
$localdir = dirname($file);
if (!$this->isDirectory($file)) {
$destination = $dir . '/' . basename($file);
$this->move($file, $destination);
}
if ($this->isDirectory($localdir) && $this->isEmptyDirectory($localdir) && ($localdir != $dir)) {
$this->remove($localdir);
}
}
}