Using PHP 5.3.3 (stable) on Linux CentOS 5.5.
Here's my folder structure:
www/myFolder/
www/myFolder/testFolder/
www/myFolder/testFile.txt
Using scandir() against the "myFolder" folder I get the following results:
.
..
testFolder
testFile.txt
I'm trying to filter out the folders from the results and only return files:
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir($file))
{
echo $file.'\n';
}
}
The expected results are:
testFile.txt
However I'm actually seeing:
testFile.txt
testFolder
Can anyone tell me what's going wrong here please?
You need to change directory or append it to your test. is_dir returns false when the file doesn't exist.
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir("myFolder/$file"))
{
echo $file.'\n';
}
}
That should do the right thing
Doesn't is_dir() take a file as a parameter?
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir($file))
{
echo $file.'\n';
}
}
Already told you the answer here: http://bugs.php.net/bug.php?id=52471
If you were displaying errors, you'd see why this isn't working:
Warning: Wrong parameter count for is_dir() in testFile.php on line 16
Now try passing $file to is_dir()
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir($file))
{
echo $file.'\n';
}
}
If anyone who comes here is interested in saving the output to an array, here's a fast way of doing that (modified to be more efficient):
$dirPath = 'dashboard';
$dir = scandir($dirPath);
foreach($dir as $index => &$item)
{
if(is_dir($dirPath. '/' . $item))
{
unset($dir[$index]);
}
}
$dir = array_values($dir);
Related
Is there a way to get all the files with a specific name from a folder with php?
For example I have in folder next files:
6546-da6sd.png
465-dasd.jpg
654-548484.jpg
654-sasaf.png
654-sakj879.jpg
776-54fsdfs.png
....
I want to get all files that start with "654-" (but not the first (6546-da6sd.png))
Thank You!
you can use glob() and strpos() like:
<?php
$dir = 'files/';
$key = '654-';//search key
foreach (glob("$dir*") as $file) {
$file = str_replace($dir,'',$file);
if (strpos($file, $key) == 0) {
echo($file."<br>");
}
}
?>
I want to read html file name from directory without any database. I have a code and its working properly, but two blank name it is giving, while I have only 4 file in directory.
<?php
if (is_dir('dir')) {
if ($dh = opendir('dir')) {
while (($file = readdir($dh)) !== false) {
echo "filename:".$file."<br />";
}
}
}?>
I have 4 html file and output should be:
filename:aaaaaa kjnnk_13.html
filename:aaaaaa kjnnk_2.html
filename:aaaaaa kjnnk_6.html
filename:aaaaaa kjnnk_9.html
But I found 2 extra filename:
filename:.
filename:..
filename:aaaaaa kjnnk_13.html
filename:aaaaaa kjnnk_2.html
filename:aaaaaa kjnnk_6.html
filename:aaaaaa kjnnk_9.html
Please help
. is for current dir
.. is for one directory up
When using readdir you will get those 2 extra.
I prefer using glob(). That function lets you filter for html files only too
<?php
$files = glob('dir/*html');
foreach($files as $file) {
echo "filename:".$file."<br />";
}
?>
Alternatively you could use FilesystemIterator which would skip the dot files by default:
$it = new FilesystemIterator('dir');
foreach ($it as $fileinfo) {
echo $fileinfo->getFilename() . "<br/>";
}
more answers in stackoverflow:
What exactly are the benefits of using a PHP 5 DirectoryIterator over PHP 4 "opendir/readdir/closedir"?
PHP: scandir() is too slow
Difference between DirectoryIterator and FileSystemIterator
I'm trying to list all PHP files in a specified directory and for it to recursively check all sub-directories until it finds no more, there could be numerous levels.
The function I have below works fine with the exception that it only recurses down one level.
I've spent hours trying to see where I'm going wrong, I'm calling the scanFiles() when it finds a new directory but this only seems to work one level down and stop, any help greatly appreciated.
Updated:
function scanFiles($pParentDirectory)
{
$vFileArray = scandir($pParentDirectory);
$vDirectories = array();
foreach ($vFileArray as $vKey => $vValue)
{
if (!in_array($vValue, array('.', '..')) && (strpos($vValue, '.php') || is_dir($vValue)))
{
if (!is_dir($vValue))
$vDirectories[] = $vValue;
else
{
$vDirectory = $vValue;
$vSubFiles = scanFiles($vDirectory);
foreach ($vSubFiles as $vKey => $vValue)
$vDirectories[] = $vDirectory.DIRECTORY_SEPARATOR.$vValue;
}
}
}
return $vDirectories;
}
You can do this easily like this:
// helper function
function getFiles(&$files, $dir) {
$items = glob($dir . "/*");
foreach ($items as $item) {
if (is_dir($item)) {
getFiles($files, $item);
} else {
if (end(explode('.', $item)) == 'php') {
$files[] = basename($item);
}
}
}
}
// usage
$files = array();
getFiles($files, "myDir");
// debug
var_dump($files);
myDir looks like this: has php files in all dirs
Output:
P.S. if you want the function to return the full path to the found .php files, remove the basename() from this line:
$files[] = basename($item);
This will then produce result like this:
hope this helps.
This is because $vDirectory is just a folder name, so scanDir looks in the current folder for it, not the sub folder.
What you want to do is to pass in the path to the folder, not just the name. This should be as simple as changing your recursive call to scanFiles($pParentDirectory . DIRECTORY_SEPARATOR . $vDirectory)
Your main problem is functions like scanDir or isDir need the full file path to work.
If you pass the full file path to them, it should work correctly.
hi there i am using the following function to list all the files and folders in a directory.
<?php
function listFolderFiles($dir){
$ffs = scandir($dir);
foreach($ffs as $ff){
echo $ff . "<br/>";
}
}
?>
but the problem seems to be i'm getting all the folders in the directory alright but i'm also getting a . and a ... something like the one below.
.
..
direc
img
music
New Text Document.txt
and i am using the following function like: listFolderFiles('MyFolder');
what i want to do is get all the folders and files but not the . and the .., what have i done wrong and how can i get what i want. thanks!
Easy way to get rid of the dots that scandir() picks up in Linux environments:
<?php
$ffs = array_diff(scandir($dir), array('..', '.'));
?>
You can use glob quite easily, which puts the filenames into an array:
print_r(glob("*.*"));
example:
// directory name
$directory = "/";
// get in directory
$files = glob($directory . "*");
$d = 0; // init dir array count
$f = 0; // init file array count
// directories and files
foreach($files as $file) {
if(is_dir($file)) {
array($l['directory'][$d] = $file);
$d++;
} else {
array($l['file'][$f] = $file);
$f++;
}
}
print_r($l);
NOTE: scandir will also pick up hidden files such as .htaccess, etc. That is why the glob method should be considered instead, unless of course you want to show them.
This should do it!
<?php
function listFolderFiles($dir){
$ffs = scandir($dir);
foreach($ffs as &$ff){
if ($ff != '.' && $ff != '..') {
echo $ff . "<br/>";
}
}
}
?>
$value can = a folder structure to the language file. Example: languages/english.php
$value can also = the files name. Example: english.php
So I need to get the current folder that $value is in and delete the folder ONLY if there are no other files/folders within that directory (after deleting the actual file as I am doing already, ofcourse).
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
#unlink($module_path . '/' . $value);
// Now I need to delete the folder ONLY if there are no other directories inside the folder where it is currently at.
// And ONLY if there are NO OTHER files within that folder also.
}
}
How can I do this?? And wondering if this can be done without using a while loop, since a while loop within a foreach loop could take some time, and need this to be as quick as possible.
And just FYI, the $module_path should never be deleted. So if $value = english.php, it should never delete the $module_path. Ofcourse, there will always be another file in there, so checking for this is not necessary, but won't hurt either way.
Thanks guys :)
EDIT
Ok, now I'm using this code here and it is NOT working, it is not removing the folders or the files, and I don't get any errors either... so not sure what the problem is here:
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
if (#unlink($module_path . '/' . $value))
#rmdir(dirname($module_path . '/' . $value));
}
}
NEVERMIND, this works a CHARM!!! Cheers Everyone!!
The easyest way is try to use rmdir. This don't delete folder if it is not empty
rmdir($module_path);
also you can check is folder empty by
if(count(glob($module_path.'*'))<3)//delete
2 for . and ..
UPD: as I reviewed maybe you should replace $module_path by dirname($module_path.'.'.$value);
Since the directory you care about might be part of the $value, you need to use dirname to figure out what the parent directory is, you can't just assume that it's $module_path.
$file_path = $module_path . '/' . $value;
if (#unlink($file_path)) {
#rmdir(dirname($file_path));
}
if (is_file($value)) {
unlink($value);
} else if (is_dir($value)) {
if (count(scandir($value)) == 2) }
unlink($value)
}
}
http://php.net/manual/en/function.is-dir.php
http://www.php.net/manual/en/function.scandir.php
The code below will take a path, check if it is a file (i.e. not a directory). If it is a file, it will extract the directory name, then delete the file, then iterate over the dir and count the files in it, if the files are zero it'll delete the dir.
Code is as an example and should work, however privileges and environment setup may result in it not working.
<?php
if(!is_dir ( string $filename )){ //if it is a file
$fileDir = dirname ( $filename );
if ($handle = opendir($fileDir)) {
echo "Directory handle: $handle\n";
echo "Files:\n";
$numFiles=0;
//delete the file
unlink($myFile);
//Loop the dir and count the file in it
while (false !== ($file = readdir($handle))) {
$numFiles = $numFiles + 1;
}
if($numFiles == 0) {
//delete the dir
rmdir($fileDir);
}
closedir($handle);
}
}
?>