Is it possible to exclude hidden files and folders from the readdir() function? I have a directory where there are many folders and some hidden folders. I want to read all folders except the hidden ones.
Thanks for any help.
Kcssm
If you just want to exclude files starting with a dot, ".", you can do something like this:
$files = readdir('/path/to/folder');
$files = array_filter($files, create_function('$a','return ($a[0]!=".");'));
This will only return files that don't start with dot "."
On windows, hidden files work differently, I don't know how to find those out.
You can exclude files and folders which starting "." by using following code
$ignoreList = array('cgi-bin', '.', '..', '._');
if ($directory = opendir(APPPATH . 'controllers/user')) {
while (false !== ($filename = readdir($directory))) {
if (!in_array($filename, $ignoreList) and substr($filename, 0, 1) != '.') {
echo $filename."<br>";
}
}
}
Use SPL iterators: DirectoryIterator + FilterIterator.
You could also use scandir with preg_grep to hide all files and folders starting with a ".". Please refer below code,
$dir = '/Users/Umesh/Sites/';
$files = preg_grep('/^([^.])/', scandir($dir));
print_r($files);
?>
Related
I have a cache folder that contains many other folders. In each of these folders are images (each folder contains a series of images for a particular product). The filenames are in the format something like:
image1-1200x1800.jpg
image1-40x40.jpg
image1-480x600w.jpg
For this example, I'm trying to search through the subfolders of the cache directory and rename all the substrings "image1" that are found in the filenames to "great", so the above would be renamed to:
great-1200x1800.jpg
great-40x40.jpg
great-480x600w.jpg
I have the following but the path to the files is unknown - it could be in any subfolder of the cache directory":
<?php
if ($handle = opendir('/path/to/files')) {
while (false !== ($fileName = readdir($handle))) {
$newName = str_replace("image1","great",$fileName);
rename($fileName, $newName);
}
closedir($handle);
}
?>
Any help would be much appreciated thanks.
Recursion means you have function calling itself. You could make a function which calls itself with the pathname if the current "file" is a directory.
But fortunately you can use a recursive iterator which is included in PHP.
$search = 'image1';
$replace = 'great';
$path = '/path/to/files/';
$iterator = new RecursiveDirectoryIterator($path);
foreach(new RecursiveIteratorIterator($iterator) as $file) {
if ($file->isFile() && str_contains($file->getFilename(), $search)) {
rename($file->getPathName(), str_replace($search, $replace, $file->getPathName()));
}
}
Note: str_contains() works with PHP8+
For prior versions use
false !== strpos($file->getFilename(), $search)
I'd like to list the names of files from a specific location, without names of the subdirectories and files they may contain.
I've used CI's directory_map function with a success, but had to make a small workaround to get rid of the folder names in not quite a neat way:
$files = directory_map('src/img/example/', 1);
foreach($files as $i => $file) {
if(strpos($file, '\\') !== false) {
unset($files[$i]);
}
}
I'm sure there has to be a way easier and better solution, but had no luck finding it
You can get an array of filenames in a one-liner, using scandir()
http://php.net/manual/en/function.scandir.php
Here's an example that does an array_diff() to remove the "." and ".." directories.
$files = array_diff(scandir('src/img/example'), array('..', '.'));
You can also use array_filter().
$files = array_filter(scandir('src/img/example'), function($item) {
return !is_dir('directory/' . $item);
});
a possible option would be to use a DirectoryIterator
$arrFiles = [];
foreach (new DirectoryIterator('src/img/example/') as $objFile)
{
if($objFile->isFile()) $arrFiles[] = $objFile->getFilename();
}
(Well what I gone through a lot of posts here on stackoverflow and other sites. I need a simple task, )
I want to provide my user facility to click on upload file from his account, then select a directory and get the list of all the files names inside that directory.
According to the posts here what I got is I have to pre-define the directory name, which I want to avoid.
Is there a simple way to click a directory and get all the files names in an array in PHP? many thanks in advance!
$dir = isset($_POST['uploadFile']) ? _SERVER['DOCUMENT_ROOT'].'/'.$_POST['uploadFile'] : null;
if ($_POST['uploadFile'] == true)
{
foreach (glob($dir."/*.mp3") as $filename) {
echo $filename;
}
}
I will go ahead and post a sample of code I am currently using, with a few changes, although I would normally tell you to look it up on google and try it first.
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
echo $file;
}
closedir($handle);
}
This will display the entire contents of a directory... including: ".", "..", any sub-directories, and any hidden files. I am sure you can figure out a way to hide those if it is not desirable.
<?php
$files=glob("somefolder/*.*");
print_r($files);
?>
Take a look at the Directory class (here) and readdir()
I'm confused what do you want, all files or only some files?
But if you want array of folders and files, do this
$folders = array();
$files = array();
$dir = opendir("path");
for($i=0;false !== ($file = readdir($dir));$i++){
if($file != "." and $file != ".."){
if(is_file($file)
$files[] = $file;
else
$folders[] = $file;
}
}
And if only some folders you want, later you can delete them from array
I always use this amazing code to get file lists:
$THE_PATTERN=$_SERVER["DOCUMENT_ROOT"]."/foldername/*.jpg";
$TheFilesList = #glob($THE_PATTERN);
$TheFilesTotal = #count($TheFilesList);
$TheFilesTotal = $TheFilesTotal - 1;
$TheFileTemp = "";
for ($TheFilex=0; $TheFilex<=$TheFilesTotal; $TheFilex++)
{
$TheFileTemp = $TheFilesList[$TheFilex];
echo $TheFileTemp . "<br>"; // here you can get full address of files (one by one)
}
I am using the following code to get a list of images in a directory:
$files = scandir($imagepath);
but $files also includes hidden files. How can I exclude them?
On Unix, you can use preg_grep to filter out filenames that start with a dot:
$files = preg_grep('/^([^.])/', scandir($imagepath));
I tend to use DirectoryIterator for things like this which provides a simple method for ignoring dot files:
$path = '/your/path';
foreach (new DirectoryIterator($path) as $fileInfo) {
if($fileInfo->isDot()) continue;
$file = $path.$fileInfo->getFilename();
}
$files = array_diff(scandir($imagepath), array('..', '.'));
or
$files = array_slice(scandir($imagepath), 2);
might be faster than
$files = preg_grep('/^([^.])/', scandir($imagepath));
function nothidden($path) {
$files = scandir($path);
foreach($files as $file) {
if ($file[0] != '.') $nothidden[] = $file;
return $nothidden;
}
}
Simply use this function
$files = nothidden($imagepath);
I encountered a comment from php.net, specifically for Windows systems: http://php.net/manual/en/function.filetype.php#87161
Quoting here for archive purposes:
I use the CLI version of PHP on Windows Vista. Here's how to determine if a file is marked "hidden" by NTFS:
function is_hidden_file($fn) {
$attr = trim(exec('FOR %A IN ("'.$fn.'") DO #ECHO %~aA'));
if($attr[3] === 'h')
return true;
return false;
}
Changing if($attr[3] === 'h') to if($attr[4] === 's') will check for system files.
This should work on any Windows OS that provides DOS shell commands.
I reckon because you are trying to 'filter' out the hidden files, it makes more sense and looks best to do this...
$items = array_filter(scandir($directory), function ($item) {
return 0 !== strpos($item, '.');
});
I'd also not call the variable $files as it implies that it only contains files, but you could in fact get directories as well...in some instances :)
use preg_grep to exclude files name with special characters for e.g.
$dir = "images/";
$files = preg_grep('/^([^.])/', scandir($dir));
http://php.net/manual/en/function.preg-grep.php
Assuming the hidden files start with a . you can do something like this when outputting:
foreach($files as $file) {
if(strpos($file, '.') !== (int) 0) {
echo $file;
}
}
Now you check for every item if there is no . as the first character, and if not it echos you like you would do.
Use the following code if you like to reset the array index too and set the order:
$path = "the/path";
$files = array_values(
preg_grep(
'/^([^.])/',
scandir($path, SCANDIR_SORT_ASCENDING)
));
One line:
$path = "daten/kundenimporte/";
$files = array_values(preg_grep('/^([^.])/', scandir($path, SCANDIR_SORT_ASCENDING)));
scandir() is a built-in function, which by default select hidden file as well,
if your directory has only . & .. hidden files then try selecting files
$files = array_diff(scandir("path/of/dir"),array(".","..")) //can add other hidden file if don't want to consider
I am still leaving the checkmark for seengee's solution and I would have posted a comment below for a slight correction to his solution.
His solution masks the directories(. and ..) but does not mask hidden files like .htaccess
A minor tweak solves the problem:
foreach(new DirectoryIterator($curDir) as $fileInfo) {
//Check for something like .htaccess in addition to . and ..
$fileName = $fileInfo->getFileName();
if(strlen(strstr($fileName, '.', true)) < 1) continue;
echo "<h3>" . $fileName . "</h3>";
}
I have a directory: Audio/ and in that will be mp3 files only. I'm wanting to automate the process of creating links to those files. Is there a way to read a directory and add filenames within that directory to an array?
It'd be doubly cool if we could do an associative array, and have the key be the file name minus the .mp3 tag.
Any ideas?
To elaborate: I actual have several Audio/ folders and each folder contains mp3s of a different event. The event details are being pulled from a database and populating a table. That's why I'm duplicating code, because right now in each Audio/ folder, I'm having to define the filenames for the download links and define the filenames for the mp3 player.
Thank you! This will greatly simplify my code as right now I'm repeating tons of code over and over!
The SPL way is with DirectoryIterator:
$files = array();
foreach (new DirectoryIterator('/path/to/files/') as $fileInfo) {
if($fileInfo->isDot() || !$fileInfo->isFile()) continue;
$files[] = $fileInfo->getFilename();
}
And for completeness : you could use glob as well :
$files = array_filter(glob('/path/to/files/*'), 'is_file');
This will return all files (but not the folders), you can adapt it as needed.
To get just the filenames (instead of files with complete path), just add :
$files = array_map('basename', $files);
Yes: use scandir(). If you just want the name of the file without the extension, use basename() on each element in the array you received from scandir().
This should be able to do what you're looking for:
// Read files
$files = scandir($dirName);
// Filter out non-files ('.' or '..')
$files = array_filter($files, 'is_file');
// Create associative array ('filename' => 'filename.mp3')
$files = array_combine(array_map('basename', $files), $files);
Sure...I think this should work...
$files[] = array();
$dir = opendir("/path/to/Audio") or die("Unable to open folder");
while ($file = readdir($dir)) {
$cleanfile = basename($file);
$files[$cleanfile] = $file;
}
closedir($dir);
I imagine that should work...
$results = array();
$handler = opendir($directory);
while ($file = readdir($handler)) {
if ($file != "." && $file != "..") {
$results[] = $file;
}
}
closedir($handler);
this should work, if you want any files to be excluded from the array, just add them to the if statement, same for file extensions