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
}
}
Related
For each document (.pdf, .txt, .docx ecc) I have also a corresponding json file with the same filename.
Example:
file1.json,
file1.pdf,
file2.json,
file2.txt,
filex.json,
filex.pdf,
But I got also some json files which are not accompanied with the corresponding document.
I want to delete all json files which have no corresponding document. Im really stucked because I cant find a proper solution to my problem.
I know how to scandir() get the filename, extensions from pathinfo() ecc. but the issue is that for each json file I find in directory I have to perform another foreach on that directory excluding all json files and see If the same filename exists or not so than I can decide to delete it. (This is how I think to solve it).
The problem here is with performance since there are millions of files and for each json I have to run a foreach on millions of files.
Can anyone guide me to a better solution?
Thank you!
Edit: Since no one will help without first posting a piece of code (and this approach in stackoverflow is definitively wrong) here is how I'm trying.:
<?php
$dir = "2000/";
$files = scandir($dir);
foreach ($files as $file) {
$fullName = pathinfo($file);
if ($fullName['extension'] === 'json') {
if (!in_array($fullName['filename'].'.pdf', $files)){
unlink($dir.$file);
}
}
}
Now as you can see I can only search only for one type of document (.pdf in this case). I want to search for every extension excluding .json and also I don't want that for each json file to run a foreach/in_array() but achieving all this in just one foreach.
Maybe you should consider it in another way? I mean, iterate through all files, and try to find corresponding files to json, if not found remove it.
It would look like follows:
$dir = "2000/";
foreach (glob($dir . "*.json") as $file) {
$file = new \SplFileInfo($dir . $file);
if (count(glob($dir . $file->getBasename('.' . $file->getExtension()) . ".*")) === 1) {
unlink($dir . $file->getFilename());
}
}
Manual
PHP: SplFileInfo
PHP: glob
How about this function?
What does foreach and rmdir($file) do in this code?
function rmDirectory($dir)
{
foreach (glob($dir . '/*') as $file) {
if (is_dir($file))
rmdir($file);
else
unlink($file);
}
rmdir($dir);
}
The foreach construct provides an easy way to iterate over arrays of $dir.
glob — Find pathnames matching a pattern
rmdir — Removes directory
Delete all files and empty directories under $dir
If the $dir is empty, delete it
The glob() function returns an array of filenames or directories
matching a specified pattern.
Source. Your foreach traverses each items found at the pattern specified as parameter. For each of them, is_dir checks whether they are directories. If the current $file happens to be a directory, then it is removed using rmdir, otherwise it is a file and is removed using unlink. Finally $dir is removed as well.
rmDirectory essentially removes the content (folders and files) of a directory and then removes the directory itself.
I am creating a WordPress plugin which allows a user to apply sorting rules to a particular template (page, archive, single etc). I am populating list of pages using PHP scandir like so:
$files = scandir(get_template_directory());
The problem is that I keep single.php templates in a '/single' subfolder so these templates are not being called by the above function.
How can I use multiple directories within the scandir function (perhaps an array?) or will I need a different solution?
So basically I am trying to:
$files = scandir( get_template_directory() AND get_template_directory().'/single' );
My current solution (not very elegant as it requires 2 for each loops):
function query_caller_is_template_file_get_template_files()
{
$template_files_list = array();
$files = scandir(get_template_directory());
$singlefiles = scandir(get_template_directory().'/single');
foreach($files as $file)
{
if(strpos($file, '.php') === FALSE)
continue;
$template_files_list[] = $file;
}
foreach($singlefiles as $singlefile)
{
if(strpos($file, '.php') === FALSE)
continue;
$template_files_list[] = $singlefile;
}
return $template_files_list;
}
First, there's not really anything wrong about what you're doing. You have two directories, so you do the same thing twice. Of course you could make it look a little cleaner and avoid the blatant copy paste:
$files = array_merge(
scandir(get_template_directory()),
scandir(get_template_directory().'/single')
);
Now just iterate over the single array.
In your case, getting the file list recursively doesn't make sense, as there may be subdirectories you don't want to check. If you did want to recurse into subdirectories, opendir() and readdir() along with is_dir() would allow you to build a recursive scan function.
You could event tighten up the '.php' filter part a bit with array_filter().
$files = array_filter($files, function($file){
return strpos($file, '.php');
});
Here I'm assuming that should a file start with .php you're not really interested in it making your list (as strpos() will return the falsy value of 0 in that case). I'm also assuming that you're sure there will be no files that have .php in the middle somewhere.
Like, template.php.bak, because you'll be using version control for something like that.
If however there is the chance of that, you may want to tighten up your check a bit to ensure the .php is at the end of the 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;
}
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).