PHP: Using glob() to list *.txt and directories? - php

Instead of listing all the files and directories
foreach(glob("/*") as $file) {
...
}
Is there a way to filter *.txt files and directories? Because with this example
foreach(glob("/*.txt") as $file) {
...
}
Will only get the *.txt files, but not the directories. But to list only directories, this will work:
foreach(glob("/*", GLOB_ONLYDIR) as $file) {
...
}
but will left out the *.txt files. I am trying to avoid using preg_match() or similar operations post reading the directory because it will waste server resources if there are around 5000 unnecessary files (image files with *.jpg, *.png).
Thank you.

Also tried GLOB_BRACE, but it didn't work, so had to use the following code:
$aDir1 = glob('/*.txt'); // current directory
$aDir2 = glob('/*/*.txt'); // subdirectory, one level below
$aDir = asort(array_merge($aDir1, $aDir2));
Thank you.

Related

What is the best method to read a folder sub directory and files in those sub directory?

I have a image folder which contains sub directory for each album of images like
Images
Images/Album1
Images/Album2
in PHP file
I create a link for each album using a thumbnail for the album using GLOB to read all folders under Images
$dir=glob('images/*');
$dir_listing=array();
foreach($dir as $list)
{
if(is_dir($list))
$dir_listing[]= (basename($list));
}
$thumbs=glob('images/thumbnails/*');
$count=0;
foreach($thumbs as $th )
{
echo" $dir_listing <br/>";
echo"<a href='$dir_listing[$count]' ><img src='$th' /> </a>";
$count++;
}
I use Glob on each page load to get list of directories and images.
I want to know if there is a better way of doing this.
I also want to get list of all files and folder based on there Last Modified time in descending Order {Latest files and Folders first}.
Is using Glob correct or should we save the sub-directories and files in text file and read from it?
I can't tell you for sure if there is a better way of doing this, but your code should definitely work.
Using glob() is the right approach only if you have a relatively low number of files in the directory (<10,000), because if yoy have a lot of files then you could get a "Allowed memory size of XYZ bytes exhausted ..." error. In this case, it is best to use opendir();
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
// do something with the file
// note that '.' and '..' is returned even
}
closedir($handle);
Finally, use the flag GLOB_NOSORT on glob() so the end result is just like its listed on the directory in case that may be used to give you results based on last modified date.
Hope this helps.

PHP Count through different directories and see which ones have 0 files in them

I have the following folder structure:
images/photo-gallery/2e/
72/
rk/
u3/
va/
yk/
... and so on. Basically, each time an image is uploaded it hashes the name and then creates a folder with the first two letters. So inside of 2e is 2e0gpw1p.jpg
Here's the thing... if I delete an image, it will delete the file but it will keep the folder that it's in. Now when I have a TON of images uploaded, that will be fine since a lot of images will share the same folder.. but until then, I will end up having a bunch of empty directories.
What I want to do is search through the photo-gallery folder and go through each directory and see which folders are empty.. if there are any empty folders then it will remove it.
I know how to do that for a single directory, like the 2e folder. But how would I do it for all the folders inside the photo-gallery folder?
The PHP function rmdir() will throw a warning if the directory is not empty, so you can use it on non-empty directories without risking deleting them. Combine that with scandir() and array_slice (to remove . and ..), and you can do this:
foreach(array_slice(scandir('images/photo-gallery'),2) as $dir) {
#rmdir('images/photo-gallery/' . $dir); // use # to silence the warning
}
while you could do with with php, i'm inclined to use the os for such a task. Of course you can call the below with php
find <parent-dir> -depth -type d -empty -exec rmdir -v {} \;
PLEASE READ THIS WARNING I DID NOT TEST BUT HAVE USED SIMILAR CODE DOZENS OF TIMES. FAMILURIZE YOURSELF WITH THIS AND DO NOT USE IF YOU DO NOT UNDERSTAND WHAT IT IS DOING THIS COULD POTENTIALLY WIPE YOUR SITE FROM THE SERVER.
EDIT BACKUP EVERYTHING BEFORE TRYING THIS YOUR FIRST TIME THE PATH IS VERY VERY IMPORTANT!
Ok with that said this is quite easy :)
<?php
function recursiveDelete($path){
$ignore = array(
'cgi-bin',
'.',
'..'
); // Directories to ignore
$dh = opendir($path); // Open the directory
while(false !== ($file = readdir($dh))){ // Loop through the directory
if(!in_array($file, $ignore)){ // Check that this file is not to be ignored
if(is_dir($path."/".$file)){ // Its a directory, keep going
if(!iterator_count(new DirectoryIterator($path."/".$file)))
rmdir($path."/".$file); // its empty delete it
} else {
recursiveDelete($path."/".$file);// Recursive call to self
}
}
}
}
closedir($dh); // All Done close the directory
}
// WARNING IMPROPERLY USED YOU CAN DUMP YOUR ENTIRE SERVER USE WITH CAUTION!!!!
// I WILL NOT BE HELD RESPONSIBLE FOR MISUSE
recursiveDelete('/some/directoy/path/to/your/gallery');
?>

PHP glob() doesnt find .htaccess

Simple question - How to list .htaccess files using glob()?
glob() does list "hidden" files (files starting with . including the directories . and ..), but only if you explicitly ask it for:
glob(".*");
Filtering the returned glob() array for .htaccess entries with preg_grep:
$files = glob(".*") AND $files = preg_grep('/\.htaccess$/', $files);
The alternative to glob of course would be just using scandir() and a filter (fnmatch or regex):
preg_grep('/^\.\w+/', scandir("."))
in case any body come to here,
since the SPL implemented in PHP, and offers some cool iterators, you may make use of the to list your hidden files such as .htaccess files or it's alternative hidden linux files.
using DirectoryIterator to list all of directory contents and excluding the . and .. as follows:
$path = 'path/to/dir';
$files = new DirectoryIterator($path);
foreach ($files as $file) {
// excluding the . and ..
if ($file->isDot() === false) {
// make some stuff
}
}

Select file(s) in a directory based upon complex filename

I have audio files in var/
This is the file name
2-3109999999-3246758493-1271129518-1271129505.6.wav
Format
2=campaign id
3109999999=caller id
3246758493=number called
1271129518=timestamp call ended
1271129505=timestamp call started
6=call id
If I were to pass just the number called which was 3246758493, how can I find all the files without defining all the other variables(such as timestamp, etc) and just the files that have that number in the filename?
You would need to loop though the folder: http://php.net/manual/en/function.readdir.php
Then for each of the files in the folder, try and match it to the file that was requested using regex I guess?
http://www.txt2re.com/index-php.php3?s=2-3109999999-3246758493-1271129518-1271129505.6.wav&8
You could also use a DirectoryIterator to scan the folder and a RegexIterator to filter the files based on a pattern.
$id = '3246758493';
$files = new RegexIterator(new DirectoryIterator('var/'),
"#^\d-\d{10}-$id-\d{10}-\d{10}\.\d\.wav$#D");
foreach ($files as $fileinfo) {
echo $fileinfo . PHP_EOL;
}

Searching for specific file extensions in a folder/directory (PHP)

I'm trying to design a program in PHP that would allow me to find files with specific file extensions (example .jpg, .shp etc) in a known directory which consists of multiple folders.
Sample code, documentation or information about what methods I will be required to use will be much appreciated.
glob is pretty easy:
<?php
foreach (glob("*.txt") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
There are a few suggestions for recursive descent at the readdir page.
Take a look at PHP's SPL DirectoryIterator.
I believe PHP's glob() function is exactly what you are looking for:
http://php.net/manual/en/function.glob.php
Use readdir to get a list of files, and fnmatch to work out if it matches your required filename pattern. Do all this inside a function, and call your function when you find directories. Ask another question if you get stuck implementing this (or comment if you really have no idea where to start).
glob will get you all the files in a given directory, but not the sub directories. If you need that too, you will need to: 10. get recursive, 20. goto 10.
Here's the pseudo pseudocode:
function getFiles($pattern, $dir) {
$files = glob($dir . $pattern);
$folders = glob($dir, GLOB_ONLYDIR);
foreach ($folders as $folder) {
$files = $files + getFiles($folder);
}
return $files;
}
The above will obviously need to be tweaked to get it working, but hopefully you get the idea (remember not to follow directory links to ".." or "." or you'll be in infinite loop town).

Categories