So I managed to get all files in my directory using this:
$dir = PUBLIC_DIRECTORY . '/' . $login_session . '/';
$files = array();
$DirectoryIterator = new RecursiveDirectoryIterator($dir);
$IteratorIterator = new RecursiveIteratorIterator($DirectoryIterator, RecursiveIteratorIterator::SELF_FIRST);
foreach ($IteratorIterator as $file) {
$path = $file;
if ($file->isFile())
$files[] = realpath($path);
}
which resulted to this:
C:\xampp\htdocs\fms\public\kei\docx\FMS.docx
C:\xampp\htdocs\fms\public\kei\jpg\1.jpg
Now i used the code below which should move the files from inside their directory to C:\xampp\htdocs\fms\public\kei\Bin\ when aged
foreach($files as $f) {
if (filemtime($f) < time() - 86400) {
rename($f, realpath($dir . "/Bin/" . basename($f));
}
}
but nothing happens for some reasons. I tried different things to get the filename like...
echo realpath($dir . "/Bin/") . basename($f);
but this code shows
C:\xampp\htdocs\fms\public\kei\BinFMS.docx
C:\xampp\htdocs\fms\public\kei\Bin1.jpg
I managed to fixed it by doing this
$bin = "\Bin\";
and this rename($f, realpath($dir) . $bin . basename($f));
Related
i would like to create a PHP script that delete files from multiple folders/paths.
I managed something but I would like to adapt this code for more specific folders.
This is the code:
<?php
function deleteOlderFiles($path,$days) {
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
$filelastmodified = filemtime($path . $file);
if((time() - $filelastmodified) > $days*24*3600)
{
if(is_file($path . $file)) {
unlink($path . $file);
}
}
}
closedir($handle);
}
}
$path = 'C:/Users/Legion/AppData/Local/Temp';
$days = 7;
deleteOlderFiles($path,$days);
?>
I would like to make something like to add more paths and this function to run for every path.
I tried to add multiple path locations but it didn't work because it always takes the last $ path variable.
For exemple:
$path = 'C:/Users/Legion/AppData/Local/Temp';
$path = 'C:/Users/Legion/AppData/Local/Temp/bla';
$path = 'C:/Users/Legion/AppData/Local/Temp/blabla';
$path = 'C:/Users/Legion/AppData/Local/Temp/blalbalba';
$days = 7;
deleteOlderFiles($path,$days);
Thank you for you help!
The simple solution, call the function after setting the parameter not after setting all the possible parameters into a scalar variable.
$days = 7;
$path = 'C:/Users/Legion/AppData/Local/Temp';
deleteOlderFiles($path,$days);
$path = 'C:/Users/Legion/AppData/Local/Temp/bla';
deleteOlderFiles($path,$days);
$path = 'C:/Users/Legion/AppData/Local/Temp/blabla';
deleteOlderFiles($path,$days);
$path = 'C:/Users/Legion/AppData/Local/Temp/blalbalba';
deleteOlderFiles($path,$days);
Alternatively, place the directories in an array and then call the funtion from within a foreach loop.
$paths = [];
$paths[] = 'C:/Users/Legion/AppData/Local/Temp';
$paths[] = 'C:/Users/Legion/AppData/Local/Temp/bla';
$paths[] = 'C:/Users/Legion/AppData/Local/Temp/blabla';
$paths[] = 'C:/Users/Legion/AppData/Local/Temp/blalbalba';
$days = 7;
foreach ( $paths as $path){
deleteOlderFiles($path,$days);
}
It seems that you need a recursive function, i.e. a function that calls itself. In this case it calls itself when it finds a subdirectory to scan/traverse.
function delete_files($current_path, $days) {
$files_in_current_path = scandir($current_path);
foreach($files_in_current_path as $file) {
if (!in_array($release_file, [".", ".."])) {
if (is_dir($current_path . "/" . $file)) {
// Scan found subdirectory
delete_files($current_path . "/" . $file, $days);
} else {
// Here you add your code for checking date and deletion of the $file
$filelastmodified = filemtime($current_path . "/" . $file);
if((time() - $filelastmodified) > $days*24*3600) {
if(is_file($current_path . "/" . $file)) {
unlink($current_path . "/". $file);
}
}
}
}
}
}
delete_files("your/startpath/here", 7);
This code starts in your specified start path. It scans all files in that directory. If a sub directory is found, there will be a new call to delete_files, but with that sub directory as a start.
I'm using flysystem to work with my files.
I don't see an easy way to flatten a directory so I used this
public function flattenDir($dir, $destination = null) {
$files = find($dir . '/*');
foreach ($files as $file) {
$localdir = dirname($file);
if (!isDirectory($file)) {
$destination = $dir . '/' . basename($file);
move($file, $destination);
}
if (isDirectory($localdir) && isEmptyDirectory($localdir) && ($localdir != $dir)) {
remove($localdir);
}
}
}
Is there an easier way by using flysystem?
I finally used that. It also manage a few things that I needed
I'm using flysystem mount manager but this script could be easily adapted to work with the default flysystem instance.
$elements should be the result of manager->listContents('local://my_dir_to_flatten');
And $root is a string my_dir_to_flatten in my case.
public function flatten($elements , $root) {
$files = array();
$directories = array();
//Make difference between files and directories
foreach ($elements as $element) {
if( $element['type'] == 'file' ) {
array_push($files, $element);
} else {
array_push($directories, $element);
}
}
//Manage files
foreach ($files as $file) {
//Dont move file already in root
if($file['dirname'] != $root) {
//Check if filename already used in root directory
if ( $this->manager->has('local://'.$root . '/' . $file['basename']) ) {
//Manage if file don't have extension
if( isset( $file['extension']) ) {
$file['basename'] = $file['filename'] . uniqid() . '.' . $file['extension'];
} else {
$file['basename'] = $file['filename'] . uniqid();
}
}
//Move the file
$this->manager->move('local://' . $file['path'] , 'local_process://' . $root . '/' . $file['basename']);
}
}
//Delete folders
foreach ($not_files as $file) {
$this->manager->deleteDir( 'local://' . $file['path'] );
}
}
I have a piece of code that print images from a directory.
<?
$directory = 'assets/images/';
$files = glob($directory."*.{jpg}", GLOB_BRACE);
$filecount = count($files);
for($i=1; $i<=$filecount; $i++) {
echo '<img src="'.$file.'" class="img-responsive">';
}
?>
It's working perfectly.
Except that I want to display my image depending the uploaded date.
Is it possible please ?
Thanks.
Try this:
function listdir_by_date($path){
$dir = opendir($path);
$list = array();
while($file = readdir($dir)){
if ($file != '.' and $file != '..'){
// add the filename, to be sure not to
// overwrite a array key
$ctime = filectime($data_path . $file) . ',' . $file;
$list[$ctime] = $file;
}
}
closedir($dir);
krsort($list);
return $list;
}
Reference
Okie, give this a go, using your glob method:
$directory = 'assets/images/';
$images = [];
$files = glob($directory . '*.{jpg}', GLOB_BRACE);
foreach($files as $file) {
$images[] = [filectime($file), $file];
}
array_multisort($images, SORT_DESC);
foreach ($images as $image) {
echo '<img src="' . $image[1] . '" class="img-responsive"><br>';
}
Just a slightly different method then what #mayank-pandey presented, but same basic end results.
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
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