How do I write a code that repeats itself within itself? [duplicate] - php
I'm trying to go through all of the files in a directory, and if there is a directory, go through all of its files and so on until there are no more directories to go to. Each and every processed item will be added to a results array in the function below. It is not working though I'm not sure what I can do/what I did wrong, but the browser runs insanely slow when this code below is processed, any help is appreciated, thanks!
Code:
function getDirContents($dir){
$results = array();
$files = scandir($dir);
foreach($files as $key => $value){
if(!is_dir($dir. DIRECTORY_SEPARATOR .$value)){
$results[] = $value;
} else if(is_dir($dir. DIRECTORY_SEPARATOR .$value)) {
$results[] = $value;
getDirContents($dir. DIRECTORY_SEPARATOR .$value);
}
}
}
print_r(getDirContents('/xampp/htdocs/WORK'));
Get all the files and folders in a directory, don't call function when you have . or ...
Your code :
<?php
function getDirContents($dir, &$results = array()) {
$files = scandir($dir);
foreach ($files as $key => $value) {
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
if (!is_dir($path)) {
$results[] = $path;
} else if ($value != "." && $value != "..") {
getDirContents($path, $results);
$results[] = $path;
}
}
return $results;
}
var_dump(getDirContents('/xampp/htdocs/WORK'));
Output (example) :
array (size=12)
0 => string '/xampp/htdocs/WORK/iframe.html' (length=30)
1 => string '/xampp/htdocs/WORK/index.html' (length=29)
2 => string '/xampp/htdocs/WORK/js' (length=21)
3 => string '/xampp/htdocs/WORK/js/btwn.js' (length=29)
4 => string '/xampp/htdocs/WORK/js/qunit' (length=27)
5 => string '/xampp/htdocs/WORK/js/qunit/qunit.css' (length=37)
6 => string '/xampp/htdocs/WORK/js/qunit/qunit.js' (length=36)
7 => string '/xampp/htdocs/WORK/js/unit-test.js' (length=34)
8 => string '/xampp/htdocs/WORK/xxxxx.js' (length=30)
9 => string '/xampp/htdocs/WORK/plane.png' (length=28)
10 => string '/xampp/htdocs/WORK/qunit.html' (length=29)
11 => string '/xampp/htdocs/WORK/styles.less' (length=30)
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('path/to/folder'));
$files = array();
/** #var SplFileInfo $file */
foreach ($rii as $file) {
if ($file->isDir()){
continue;
}
$files[] = $file->getPathname();
}
var_dump($files);
This will bring you all the files with paths.
This is a function to get all the files and folders in a directory with RecursiveIteratorIterator.
See contructor doc : https://www.php.net/manual/en/recursiveiteratoriterator.construct.php
function getDirContents($path) {
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$files = array();
foreach ($rii as $file)
if (!$file->isDir())
$files[] = $file->getPathname();
return $files;
}
var_dump(getDirContents($path));
This could help if you wish to get directory contents as an array, ignoring hidden files and directories.
function dir_tree($dir_path)
{
$rdi = new \RecursiveDirectoryIterator($dir_path);
$rii = new \RecursiveIteratorIterator($rdi);
$tree = [];
foreach ($rii as $splFileInfo) {
$file_name = $splFileInfo->getFilename();
// Skip hidden files and directories.
if ($file_name[0] === '.') {
continue;
}
$path = $splFileInfo->isDir() ? array($file_name => array()) : array($file_name);
for ($depth = $rii->getDepth() - 1; $depth >= 0; $depth--) {
$path = array($rii->getSubIterator($depth)->current()->getFilename() => $path);
}
$tree = array_merge_recursive($tree, $path);
}
return $tree;
}
The result would be something like;
dir_tree(__DIR__.'/public');
[
'css' => [
'style.css',
'style.min.css',
],
'js' => [
'script.js',
'script.min.js',
],
'favicon.ico',
]
Source
Get all the files with filter (2nd argument) and folders in a directory, don't call function when you have . or ...
Your code :
<?php
function getDirContents($dir, $filter = '', &$results = array()) {
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if(!is_dir($path)) {
if(empty($filter) || preg_match($filter, $path)) $results[] = $path;
} elseif($value != "." && $value != "..") {
getDirContents($path, $filter, $results);
}
}
return $results;
}
// Simple Call: List all files
var_dump(getDirContents('/xampp/htdocs/WORK'));
// Regex Call: List php files only
var_dump(getDirContents('/xampp/htdocs/WORK', '/\.php$/'));
Output (example) :
// Simple Call
array(13) {
[0]=> string(69) "/xampp/htdocs/WORK.htaccess"
[1]=> string(73) "/xampp/htdocs/WORKConverter.php"
[2]=> string(69) "/xampp/htdocs/WORKEvent.php"
[3]=> string(70) "/xampp/htdocs/WORKdefault_filter.json"
[4]=> string(68) "/xampp/htdocs/WORKdefault_filter.xml"
[5]=> string(80) "/xampp/htdocs/WORKCaching/ApcCache.php"
[6]=> string(84) "/xampp/htdocs/WORKCaching/CacheFactory.php"
}
// Regex Call
array(13) {
[0]=> string(69) "/xampp/htdocs/WORKEvent.php"
[1]=> string(73) "/xampp/htdocs/WORKConverter.php"
[2]=> string(80) "/xampp/htdocs/WORKCaching/ApcCache.php"
[3]=> string(84) "/xampp/htdocs/WORKCaching/CacheFactory.php"
}
James Cameron's proposition.
My proposal without ugly "foreach" control structures is
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
$allFiles = array_filter(iterator_to_array($iterator), fn($file) $file->isFile());
You may only want to extract the filepath, which you can do so by:
array_keys($allFiles);
Still 4 lines of code, but more straight forward than using a loop or something.
Here is what I came up with and this is with not much lines of code
function show_files($start) {
$contents = scandir($start);
array_splice($contents, 0,2);
echo "<ul>";
foreach ( $contents as $item ) {
if ( is_dir("$start/$item") && (substr($item, 0,1) != '.') ) {
echo "<li>$item</li>";
show_files("$start/$item");
} else {
echo "<li>$item</li>";
}
}
echo "</ul>";
}
show_files('./');
It outputs something like
..idea
.add.php
.add_task.php
.helpers
.countries.php
.mysqli_connect.php
.sort.php
.test.js
.test.php
.view_tasks.php
** The dots are the dots of unoordered list.
Hope this helps.
Add relative path option:
function getDirContents($dir, $relativePath = false)
{
$fileList = array();
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($iterator as $file) {
if ($file->isDir()) continue;
$path = $file->getPathname();
if ($relativePath) {
$path = str_replace($dir, '', $path);
$path = ltrim($path, '/\\');
}
$fileList[] = $path;
}
return $fileList;
}
print_r(getDirContents('/path/to/dir'));
print_r(getDirContents('/path/to/dir', true));
Output:
Array
(
[0] => /path/to/dir/test1.html
[1] => /path/to/dir/test.html
[2] => /path/to/dir/index.php
)
Array
(
[0] => test1.html
[1] => test.html
[2] => index.php
)
Here's a modified version of Hors answer, works slightly better for my case, as it strips out the base directory that is passed as it goes, and has a recursive switch that can be set to false which is also handy. Plus to make the output more readable, I've separated the file and subdirectory files, so the files are added first then the subdirectory files (see result for what I mean.)
I tried a few other methods and suggestions around and this is what I ended up with. I had another working method already that was very similar, but seemed to fail where there was a subdirectory with no files but that subdirectory had a subsubdirectory with files, it didn't scan the subsubdirectory for files - so some answers may need to be tested for that case.)... anyways thought I'd post my version here too in case someone is looking...
function get_filelist_as_array($dir, $recursive = true, $basedir = '', $include_dirs = false) {
if ($dir == '') {return array();} else {$results = array(); $subresults = array();}
if (!is_dir($dir)) {$dir = dirname($dir);} // so a files path can be sent
if ($basedir == '') {$basedir = realpath($dir).DIRECTORY_SEPARATOR;}
$files = scandir($dir);
foreach ($files as $key => $value){
if ( ($value != '.') && ($value != '..') ) {
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if (is_dir($path)) {
// optionally include directories in file list
if ($include_dirs) {$subresults[] = str_replace($basedir, '', $path);}
// optionally get file list for all subdirectories
if ($recursive) {
$subdirresults = get_filelist_as_array($path, $recursive, $basedir, $include_dirs);
$results = array_merge($results, $subdirresults);
}
} else {
// strip basedir and add to subarray to separate file list
$subresults[] = str_replace($basedir, '', $path);
}
}
}
// merge the subarray to give the list of files then subdirectory files
if (count($subresults) > 0) {$results = array_merge($subresults, $results);}
return $results;
}
I suppose one thing to be careful of it not to pass a $basedir value to this function when calling it... mostly just pass the $dir (or passing a filepath will work now too) and optionally $recursive as false if and as needed. The result:
[0] => demo-image.png
[1] => filelist.php
[2] => tile.png
[3] => 2015\header.png
[4] => 2015\08\background.jpg
Enjoy! Okay, back to the program I'm actually using this in...
UPDATE Added extra argument for including directories in the file list or not (remembering other arguments will need to be passed to use this.) eg.
$results = get_filelist_as_array($dir, true, '', true);
This solution did the job for me. The RecursiveIteratorIterator lists all directories and files recursively but unsorted. The program filters the list and sorts it.
I'm sure there is a way to write this shorter; feel free to improve it.
It is just a code snippet. You may want to pimp it to your purposes.
<?php
$path = '/pth/to/your/directories/and/files';
// an unsorted array of dirs & files
$files_dirs = iterator_to_array( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),RecursiveIteratorIterator::SELF_FIRST) );
echo '<html><body><pre>';
// create a new associative multi-dimensional array with dirs as keys and their files
$dirs_files = array();
foreach($files_dirs as $dir){
if(is_dir($dir) AND preg_match('/\/\.$/',$dir)){
$d = preg_replace('/\/\.$/','',$dir);
$dirs_files[$d] = array();
foreach($files_dirs as $file){
if(is_file($file) AND $d == dirname($file)){
$f = basename($file);
$dirs_files[$d][] = $f;
}
}
}
}
//print_r($dirs_files);
// sort dirs
ksort($dirs_files);
foreach($dirs_files as $dir => $files){
$c = substr_count($dir,'/');
echo str_pad(' ',$c,' ', STR_PAD_LEFT)."$dir\n";
// sort files
asort($files);
foreach($files as $file){
echo str_pad(' ',$c,' ', STR_PAD_LEFT)."|_$file\n";
}
}
echo '</pre></body></html>';
?>
This will print the full path of all files in the given directory, you can also pass other callback functions to recursiveDir.
function printFunc($path){
echo $path."<br>";
}
function recursiveDir($path, $fileFunc, $dirFunc){
$openDir = opendir($path);
while (($file = readdir($openDir)) !== false) {
$fullFilePath = realpath("$path/$file");
if ($file[0] != ".") {
if (is_file($fullFilePath)){
if (is_callable($fileFunc)){
$fileFunc($fullFilePath);
}
} else {
if (is_callable($dirFunc)){
$dirFunc($fullFilePath);
}
recursiveDir($fullFilePath, $fileFunc, $dirFunc);
}
}
}
}
recursiveDir($dirToScan, 'printFunc', 'printFunc');
This is a little modification of majicks answer.
I just changed the array structure returned by the function.
From:
array() => {
[0] => "test/test.txt"
}
To:
array() => {
'test/test.txt' => "test.txt"
}
/**
* #param string $dir
* #param bool $recursive
* #param string $basedir
*
* #return array
*/
function getFileListAsArray(string $dir, bool $recursive = true, string $basedir = ''): array {
if ($dir == '') {
return array();
} else {
$results = array();
$subresults = array();
}
if (!is_dir($dir)) {
$dir = dirname($dir);
} // so a files path can be sent
if ($basedir == '') {
$basedir = realpath($dir) . DIRECTORY_SEPARATOR;
}
$files = scandir($dir);
foreach ($files as $key => $value) {
if (($value != '.') && ($value != '..')) {
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
if (is_dir($path)) { // do not combine with the next line or..
if ($recursive) { // ..non-recursive list will include subdirs
$subdirresults = self::getFileListAsArray($path, $recursive, $basedir);
$results = array_merge($results, $subdirresults);
}
} else { // strip basedir and add to subarray to separate file list
$subresults[str_replace($basedir, '', $path)] = $value;
}
}
}
// merge the subarray to give the list of files then subdirectory files
if (count($subresults) > 0) {
$results = array_merge($subresults, $results);
}
return $results;
}
Might help for those having the exact same expected results like me.
To whom needs list files first than folders (with alphabetical older).
Can use following function.
This is not self calling function. So you will have directory list, directory view, files
list and folders list as seperated array also.
I spend two days for this and do not want someone will wast his time for this also, hope helps someone.
function dirlist($dir){
if(!file_exists($dir)){ return $dir.' does not exists'; }
$list = array('path' => $dir, 'dirview' => array(), 'dirlist' => array(), 'files' => array(), 'folders' => array());
$dirs = array($dir);
while(null !== ($dir = array_pop($dirs))){
if($dh = opendir($dir)){
while(false !== ($file = readdir($dh))){
if($file == '.' || $file == '..') continue;
$path = $dir.DIRECTORY_SEPARATOR.$file;
$list['dirlist_natural'][] = $path;
if(is_dir($path)){
$list['dirview'][$dir]['folders'][] = $path;
// Bos klasorler while icerisine tekrar girmeyecektir. Klasorun oldugundan emin olalım.
if(!isset($list['dirview'][$path])){ $list['dirview'][$path] = array(); }
$dirs[] = $path;
//if($path == 'D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-content\upgrade'){ press($path); press($list['dirview']); die; }
}
else{
$list['dirview'][$dir]['files'][] = $path;
}
}
closedir($dh);
}
}
// if(!empty($dirlist['dirlist_natural'])) sort($dirlist['dirlist_natural'], SORT_LOCALE_STRING); // delete safe ama gerek kalmadı.
if(!empty($list['dirview'])) ksort($list['dirview']);
// Dosyaları dogru sıralama yaptırıyoruz. Deniz P. - info[at]netinial.com
foreach($list['dirview'] as $path => $file){
if(isset($file['files'])){
$list['dirlist'][] = $path;
$list['files'] = array_merge($list['files'], $file['files']);
$list['dirlist'] = array_merge($list['dirlist'], $file['files']);
}
// Add empty folders to the list
if(is_dir($path) && array_search($path, $list['dirlist']) === false){
$list['dirlist'][] = $path;
}
if(isset($file['folders'])){
$list['folders'] = array_merge($list['folders'], $file['folders']);
}
}
//press(array_diff($list['dirlist_natural'], $list['dirlist'])); press($list['dirview']); die;
return $list;
}
will output something like this.
[D:\Xampp\htdocs\exclusiveyachtcharter.localhost] => Array
(
[files] => Array
(
[0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\.htaccess
[1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\index.php
[2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\license.txt
[3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\php.php
[4] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\readme.html
[5] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-activate.php
[6] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-blog-header.php
[7] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-comments-post.php
[8] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config-sample.php
[9] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config.php
[10] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-cron.php
[11] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-links-opml.php
[12] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-load.php
[13] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-login.php
[14] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-mail.php
[15] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-settings.php
[16] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-signup.php
[17] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-trackback.php
[18] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\xmlrpc.php
)
[folders] => Array
(
[0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql
[1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-admin
[2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-content
[3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-includes
)
)
dirview output
[dirview] => Array
(
[0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\.htaccess
[1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\index.php
[2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\license.txt
[3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\php.php
[4] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\readme.html
[5] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-activate.php
[6] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-blog-header.php
[7] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-comments-post.php
[8] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config-sample.php
[9] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config.php
[10] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-cron.php
[11] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-links-opml.php
[12] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-load.php
[13] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-login.php
[14] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-mail.php
[15] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-settings.php
[16] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-signup.php
[17] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-trackback.php
[18] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\xmlrpc.php
[19] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost
[20] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql\exclusiv_excluwl.sql
[21] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql\exclusiv_excluwl.sql.zip
[22] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql
)
#A-312's solution may cause memory problems as it may create a huge array if /xampp/htdocs/WORK contains a lot of files and folders.
If you have PHP 7 then you can use Generators and optimize PHP's memory like this:
function getDirContents($dir) {
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if(!is_dir($path)) {
yield $path;
} else if($value != "." && $value != "..") {
yield from getDirContents($path);
yield $path;
}
}
}
foreach(getDirContents('/xampp/htdocs/WORK') as $value) {
echo $value."\n";
}
yield from
Ready for copy and paste function for common use cases, improved/extended version of one answer above:
function getDirContents(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array {
$results = [];
$scanAll = scandir($dir);
sort($scanAll);
$scanDirs = []; $scanFiles = [];
foreach($scanAll as $fName){
if ($fName === '.' || $fName === '..') { continue; }
$fPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath($dir . '/' . $fName));
if (strlen($excludeRegex) > 0 && preg_match($excludeRegex, $fPath . (is_dir($fPath) ? '/' : ''))) { continue; }
if (is_dir($fPath)) {
$scanDirs[] = $fPath;
} elseif ($onlyFiles >= 0) {
$scanFiles[] = $fPath;
}
}
foreach ($scanDirs as $pDir) {
if ($onlyFiles <= 0) {
$results[] = $pDir;
}
if ($maxDepth !== 0) {
foreach (getDirContents($pDir, $onlyFiles, $excludeRegex, $maxDepth - 1) as $p) {
$results[] = $p;
}
}
}
foreach ($scanFiles as $p) {
$results[] = $p;
}
return $results;
}
And if you need relative paths:
function updateKeysWithRelPath(array $paths, string $baseDir, bool $allowBaseDirPath = false): array {
$results = [];
$regex = '~^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath($baseDir)), '~') . '(?:/|$)~s';
$regex = preg_replace('~/~', '/(?:(?!\.\.?/)(?:(?!/).)+/\.\.(?:/|$))?(?:\.(?:/|$))*', $regex); // limited to only one "/xx/../" expr
if (DIRECTORY_SEPARATOR === '\\') {
$regex = preg_replace('~/~', '[/\\\\\\\\]', $regex) . 'i';
}
foreach ($paths as $p) {
$rel = preg_replace($regex, '', $p, 1);
if ($rel === $p) {
throw new \Exception('Path relativize failed, path "' . $p . '" is not within basedir "' . $baseDir . '".');
} elseif ($rel === '') {
if (!$allowBaseDirPath) {
throw new \Exception('Path relativize failed, basedir path "' . $p . '" not allowed.');
} else {
$results[$rel] = './';
}
} else {
$results[$rel] = $p;
}
}
return $results;
}
function getDirContentsWithRelKeys(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array {
return updateKeysWithRelPath(getDirContents($dir, $onlyFiles, $excludeRegex, $maxDepth), $dir);
}
This version solves/improves:
warnings from realpath when PHP open_basedir does not cover the .. directory.
does not use reference for the result array
allows to exclude directories and files
allows to list files/directories only
allows to limit the search depth
it always sort output with directories first (so directories can be removed/emptied in reverse order)
allows to get paths with relative keys
heavy optimized for hundred of thousands or even milions of files
write for more in the comments :)
Examples:
// list only `*.php` files and skip .git/ and the current file
$onlyPhpFilesExcludeRegex = '~/\.git/|(?<!/|\.php)$|^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath(__FILE__)), '~') . '$~is';
$phpFiles = getDirContents(__DIR__, 1, $onlyPhpFilesExcludeRegex);
print_r($phpFiles);
// with relative keys
$phpFiles = getDirContentsWithRelKeys(__DIR__, 1, $onlyPhpFilesExcludeRegex);
print_r($phpFiles);
// with "include only" regex to include only .html and .txt files with "/*_mails/en/*.(html|txt)" path
'~/\.git/|^(?!.*/(|' . '[^/]+_mails/en/[^/]+\.(?:html|txt)' . ')$)~is'
If you're using Laravel you can use the allFiles method on the Storage facade to recursively get all files as shown in the docs here: https://laravel.com/docs/8.x/filesystem#get-all-files-within-a-directory.
use Illuminate\Support\Facades\Storage;
class TestClass {
public function test() {
// Gets all the files in the 'storage/app' directory.
$files = Storage::allFiles(storage_path('app'))
}
}
Here is mine :
function recScan( $mainDir, $allData = array() )
{
// hide files
$hidefiles = array(
".",
"..",
".htaccess",
".htpasswd",
"index.php",
"php.ini",
"error_log" ) ;
//start reading directory
$dirContent = scandir( $mainDir ) ;
foreach ( $dirContent as $key => $content )
{
$path = $mainDir . '/' . $content ;
// if is readable / file
if ( ! in_array( $content, $hidefiles ) )
{
if ( is_file( $path ) && is_readable( $path ) )
{
$allData[] = $path ;
}
// if is readable / directory
// Beware ! recursive scan eats ressources !
else
if ( is_dir( $path ) && is_readable( $path ) )
{
/*recursive*/
$allData = recScan( $path, $allData ) ;
}
}
}
return $allData ;
}
here I have example for that
List all the files and folders in a Directory csv(file) read with PHP recursive function
<?php
/** List all the files and folders in a Directory csv(file) read with PHP recursive function */
function getDirContents($dir, &$results = array()){
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if(!is_dir($path)) {
$results[] = $path;
} else if($value != "." && $value != "..") {
getDirContents($path, $results);
//$results[] = $path;
}
}
return $results;
}
$files = getDirContents('/xampp/htdocs/medifree/lab');//here folder name where your folders and it's csvfile;
foreach($files as $file){
$csv_file =$file;
$foldername = explode(DIRECTORY_SEPARATOR,$file);
//using this get your folder name (explode your path);
print_r($foldername);
if (($handle = fopen($csv_file, "r")) !== FALSE) {
fgetcsv($handle);
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
for ($c=0; $c < $num; $c++) {
$col[$c] = $data[$c];
}
}
fclose($handle);
}
}
?>
http://myphpinformation.blogspot.in/2016/05/list-all-files-and-folders-in-directory-csv-file-read-with-php-recursive.html
I improved with one check iteration the good code of Hors Sujet to avoid including folders in the result array:
function getDirContents($dir, &$results = array()){
$files = scandir($dir);
foreach($files as $key => $value){
$path = realpath($dir.DIRECTORY_SEPARATOR.$value);
if(is_dir($path) == false) {
$results[] = $path;
}
else if($value != "." && $value != "..") {
getDirContents($path, $results);
if(is_dir($path) == false) {
$results[] = $path;
}
}
}
return $results;
}
I found this simple code:
https://stackoverflow.com/a/24981012
$Directory = new RecursiveDirectoryIterator($path);
$Iterator = new RecursiveIteratorIterator($Directory);
//Filter to get only PDF, JPEG, JPG, GIF, TIF files.
$Regex = new RegexIterator($Iterator, '/^.+(.jpe?g|.gif|.png|.tif|.pdf)$/i', RecursiveRegexIterator::GET_MATCH);
foreach($Regex as $val => $Regex){
echo "$val\n<br>";
}
Related
How to recursively iterate through files in PHP?
I have set up a basic script that is posting an array of paths to find template files inside them; currently it's only searching two levels deep and I'm having some troubles getting my head around the logic for an extensive loop to iterate all child directories until the length is 0. So if I have a structure like this: ./components ./components/template.html ./components/template2.html ./components/side/template.html ./components/side/template2.html ./components/side/second/template.html ./components/side/second/template2.html ./components/side/second/third/template.html ./components/side/second/third/template2.html It's only searching up to the "side" directory for .html files when ideally I want it to check all child directories and the passed directory for .html files. Here is my working code so far: <?php function getFiles($path){ $dh = opendir($path); foreach(glob($path.'/*.html') as $filename){ $files[] = $filename; } if (isset($files)) { return $files; } } foreach ($_POST as $path) { foreach (glob($path . '/*' , GLOB_ONLYDIR) as $secondLevel) { $files[] = getFiles($secondLevel); } $files[] = getFiles($path); } sort($files); print_r(json_encode($files)); ?>
PHP has the perfect solution for you built in. Example // Construct the iterator $it = new RecursiveDirectoryIterator("/components"); // Loop through files foreach(new RecursiveIteratorIterator($it) as $file) { if ($file->getExtension() == 'html') { echo $file; } } Resources DirectoryIterator - Manual
PHP 5 introduces iterators to iterate quickly through many elements. You can use RecursiveDirectoryIterator to iterate recursively through directories. You can use RecursiveIteratorIterator on the result to have a flatten view of the result. You can use RegexIterator on the result to filter based on a regular expression. $directory_iterator = new RecursiveDirectoryIterator('.'); $iterator = new RecursiveIteratorIterator($directory_iterator); $regex_iterator = new RegexIterator($iterator, '/\.php$/'); $regex_iterator->setFlags(RegexIterator::USE_KEY); foreach ($regex_iterator as $file) { echo $file->getPathname() . PHP_EOL; } With iterators, there are lot of ways to do the same thing, you can also use a FilterIterator (see the example on the page) For instance, if you want to select the files modified this week, you can use the following: $directory_iterator = new RecursiveDirectoryIterator('.'); $iterator = new RecursiveIteratorIterator($directory_iterator); class CustomFilterIterator extends FilterIterator { function accept() { $current=$this->getInnerIterator()->current(); return ($current->isFile()&&$current->getMTime()>time()-3600*24*7); } } $filter_iterator=new CustomFilterIterator($iterator); foreach ($filter_iterator as $file) { echo $file->getPathname() . PHP_EOL; }
Another solution is using Finder component from Symfony. It's tested and proven code. Take a look at it here: http://symfony.com/doc/current/components/finder.html
Here is working code which scans given directory $dir and all of its sub directories to any levels and return list of html files and folders containing them. <?php function find_all_files($dir) { if(!is_dir($dir)) return false; $pathinfo = ''; $root = scandir($dir); foreach($root as $value) { if($value === '.' || $value === '..') {continue;} if(is_file("$dir/$value")) { $pathinfo = pathinfo($dir.'/'.$value); if($pathinfo['extension'] == 'html') { $result[]="$dir/$value"; } continue; } foreach(find_all_files("$dir/$value") as $value) { $result[]=$value; } } return $result; } //call function $res = find_all_files('physical path to folder'); print_r($res); ?>
Universal File search in folder, sub-folder : function dirToArray($dir,$file_name) { $result = array(); $cdir = scandir($dir); foreach ($cdir as $key => $value) { if (!in_array($value,array(".",".."))) { if (is_dir($dir . DIRECTORY_SEPARATOR . $value)) { $result[$value] = dirToArray($dir . DIRECTORY_SEPARATOR . $value,$file_name); } else { if($value == $file_name){ $result[] = $value; } } } } return $result; } define('ROOT', dirname(__FILE__)); $file_name = 'template.html'; $tree = dirToArray(ROOT,$file_name); echo "<pre>".print_r($tree,1)."</pre>"; OUTPUT : Array ( [components] => Array ( [side] => Array ( [second] => Array ( [0] => template.html [third] => Array ( [0] => template.html ) ) [0] => template.html ) [0] => template.html ) [0] => template.html )
Alternative of my previous answer : $dir = 'components'; function getFiles($dir, &$results = array(), $filename = 'template.html'){ $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.'/'.$value); if(!is_dir($path)) { if($value == $filename) $results[] = $path; } else if($value != "." && $value != "..") { getFiles($path, $results); } } return $results; } echo '<pre>'.print_r(getFiles($dir), 1).'</pre>'; OUTPUT : Array ( [0] => /web/practise/php/others/test7/components/side/second/template.html [1] => /web/practise/php/others/test7/components/side/second/third/template.html [2] => /web/practise/php/others/test7/components/side/template.html [3] => /web/practise/php/others/test7/components/template.html )
Here is a generic solution: function parseDir($dir, &$files=array(), $extension=false){ if(!is_dir($dir)){ $info = pathinfo($dir); // add all files if extension is set to false if($extension === false || (isset($info['extension']) && $info['extension'] === $extension)){ $files[] = $dir; } }else{ if(substr($dir, -1) !== '.' && $dh = opendir($dir)){ while($file = readdir($dh)){ parseDir("$dir/$file", $files, $extension); } } } } $files = array(); parseDir('components', $files, 'html'); var_dump($files); OUTPUT php parseDir.php array(7) { [0]=> string(25) "components/template2.html" [1]=> string(29) "components/side/template.html" [2]=> string(30) "components/side/template2.html" [3]=> string(36) "components/side/second/template.html" [4]=> string(37) "components/side/second/template2.html" [5]=> string(42) "components/side/second/third/template.html" [6]=> string(43) "components/side/second/third/template2.html" }
List all the files and folders in a Directory with PHP recursive function
I'm trying to go through all of the files in a directory, and if there is a directory, go through all of its files and so on until there are no more directories to go to. Each and every processed item will be added to a results array in the function below. It is not working though I'm not sure what I can do/what I did wrong, but the browser runs insanely slow when this code below is processed, any help is appreciated, thanks! Code: function getDirContents($dir){ $results = array(); $files = scandir($dir); foreach($files as $key => $value){ if(!is_dir($dir. DIRECTORY_SEPARATOR .$value)){ $results[] = $value; } else if(is_dir($dir. DIRECTORY_SEPARATOR .$value)) { $results[] = $value; getDirContents($dir. DIRECTORY_SEPARATOR .$value); } } } print_r(getDirContents('/xampp/htdocs/WORK'));
Get all the files and folders in a directory, don't call function when you have . or ... Your code : <?php function getDirContents($dir, &$results = array()) { $files = scandir($dir); foreach ($files as $key => $value) { $path = realpath($dir . DIRECTORY_SEPARATOR . $value); if (!is_dir($path)) { $results[] = $path; } else if ($value != "." && $value != "..") { getDirContents($path, $results); $results[] = $path; } } return $results; } var_dump(getDirContents('/xampp/htdocs/WORK')); Output (example) : array (size=12) 0 => string '/xampp/htdocs/WORK/iframe.html' (length=30) 1 => string '/xampp/htdocs/WORK/index.html' (length=29) 2 => string '/xampp/htdocs/WORK/js' (length=21) 3 => string '/xampp/htdocs/WORK/js/btwn.js' (length=29) 4 => string '/xampp/htdocs/WORK/js/qunit' (length=27) 5 => string '/xampp/htdocs/WORK/js/qunit/qunit.css' (length=37) 6 => string '/xampp/htdocs/WORK/js/qunit/qunit.js' (length=36) 7 => string '/xampp/htdocs/WORK/js/unit-test.js' (length=34) 8 => string '/xampp/htdocs/WORK/xxxxx.js' (length=30) 9 => string '/xampp/htdocs/WORK/plane.png' (length=28) 10 => string '/xampp/htdocs/WORK/qunit.html' (length=29) 11 => string '/xampp/htdocs/WORK/styles.less' (length=30)
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('path/to/folder')); $files = array(); /** #var SplFileInfo $file */ foreach ($rii as $file) { if ($file->isDir()){ continue; } $files[] = $file->getPathname(); } var_dump($files); This will bring you all the files with paths.
This is a function to get all the files and folders in a directory with RecursiveIteratorIterator. See contructor doc : https://www.php.net/manual/en/recursiveiteratoriterator.construct.php function getDirContents($path) { $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $files = array(); foreach ($rii as $file) if (!$file->isDir()) $files[] = $file->getPathname(); return $files; } var_dump(getDirContents($path));
This could help if you wish to get directory contents as an array, ignoring hidden files and directories. function dir_tree($dir_path) { $rdi = new \RecursiveDirectoryIterator($dir_path); $rii = new \RecursiveIteratorIterator($rdi); $tree = []; foreach ($rii as $splFileInfo) { $file_name = $splFileInfo->getFilename(); // Skip hidden files and directories. if ($file_name[0] === '.') { continue; } $path = $splFileInfo->isDir() ? array($file_name => array()) : array($file_name); for ($depth = $rii->getDepth() - 1; $depth >= 0; $depth--) { $path = array($rii->getSubIterator($depth)->current()->getFilename() => $path); } $tree = array_merge_recursive($tree, $path); } return $tree; } The result would be something like; dir_tree(__DIR__.'/public'); [ 'css' => [ 'style.css', 'style.min.css', ], 'js' => [ 'script.js', 'script.min.js', ], 'favicon.ico', ] Source
Get all the files with filter (2nd argument) and folders in a directory, don't call function when you have . or ... Your code : <?php function getDirContents($dir, $filter = '', &$results = array()) { $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { if(empty($filter) || preg_match($filter, $path)) $results[] = $path; } elseif($value != "." && $value != "..") { getDirContents($path, $filter, $results); } } return $results; } // Simple Call: List all files var_dump(getDirContents('/xampp/htdocs/WORK')); // Regex Call: List php files only var_dump(getDirContents('/xampp/htdocs/WORK', '/\.php$/')); Output (example) : // Simple Call array(13) { [0]=> string(69) "/xampp/htdocs/WORK.htaccess" [1]=> string(73) "/xampp/htdocs/WORKConverter.php" [2]=> string(69) "/xampp/htdocs/WORKEvent.php" [3]=> string(70) "/xampp/htdocs/WORKdefault_filter.json" [4]=> string(68) "/xampp/htdocs/WORKdefault_filter.xml" [5]=> string(80) "/xampp/htdocs/WORKCaching/ApcCache.php" [6]=> string(84) "/xampp/htdocs/WORKCaching/CacheFactory.php" } // Regex Call array(13) { [0]=> string(69) "/xampp/htdocs/WORKEvent.php" [1]=> string(73) "/xampp/htdocs/WORKConverter.php" [2]=> string(80) "/xampp/htdocs/WORKCaching/ApcCache.php" [3]=> string(84) "/xampp/htdocs/WORKCaching/CacheFactory.php" } James Cameron's proposition.
My proposal without ugly "foreach" control structures is $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $allFiles = array_filter(iterator_to_array($iterator), fn($file) $file->isFile()); You may only want to extract the filepath, which you can do so by: array_keys($allFiles); Still 4 lines of code, but more straight forward than using a loop or something.
Here is what I came up with and this is with not much lines of code function show_files($start) { $contents = scandir($start); array_splice($contents, 0,2); echo "<ul>"; foreach ( $contents as $item ) { if ( is_dir("$start/$item") && (substr($item, 0,1) != '.') ) { echo "<li>$item</li>"; show_files("$start/$item"); } else { echo "<li>$item</li>"; } } echo "</ul>"; } show_files('./'); It outputs something like ..idea .add.php .add_task.php .helpers .countries.php .mysqli_connect.php .sort.php .test.js .test.php .view_tasks.php ** The dots are the dots of unoordered list. Hope this helps.
Add relative path option: function getDirContents($dir, $relativePath = false) { $fileList = array(); $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)); foreach ($iterator as $file) { if ($file->isDir()) continue; $path = $file->getPathname(); if ($relativePath) { $path = str_replace($dir, '', $path); $path = ltrim($path, '/\\'); } $fileList[] = $path; } return $fileList; } print_r(getDirContents('/path/to/dir')); print_r(getDirContents('/path/to/dir', true)); Output: Array ( [0] => /path/to/dir/test1.html [1] => /path/to/dir/test.html [2] => /path/to/dir/index.php ) Array ( [0] => test1.html [1] => test.html [2] => index.php )
Here's a modified version of Hors answer, works slightly better for my case, as it strips out the base directory that is passed as it goes, and has a recursive switch that can be set to false which is also handy. Plus to make the output more readable, I've separated the file and subdirectory files, so the files are added first then the subdirectory files (see result for what I mean.) I tried a few other methods and suggestions around and this is what I ended up with. I had another working method already that was very similar, but seemed to fail where there was a subdirectory with no files but that subdirectory had a subsubdirectory with files, it didn't scan the subsubdirectory for files - so some answers may need to be tested for that case.)... anyways thought I'd post my version here too in case someone is looking... function get_filelist_as_array($dir, $recursive = true, $basedir = '', $include_dirs = false) { if ($dir == '') {return array();} else {$results = array(); $subresults = array();} if (!is_dir($dir)) {$dir = dirname($dir);} // so a files path can be sent if ($basedir == '') {$basedir = realpath($dir).DIRECTORY_SEPARATOR;} $files = scandir($dir); foreach ($files as $key => $value){ if ( ($value != '.') && ($value != '..') ) { $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if (is_dir($path)) { // optionally include directories in file list if ($include_dirs) {$subresults[] = str_replace($basedir, '', $path);} // optionally get file list for all subdirectories if ($recursive) { $subdirresults = get_filelist_as_array($path, $recursive, $basedir, $include_dirs); $results = array_merge($results, $subdirresults); } } else { // strip basedir and add to subarray to separate file list $subresults[] = str_replace($basedir, '', $path); } } } // merge the subarray to give the list of files then subdirectory files if (count($subresults) > 0) {$results = array_merge($subresults, $results);} return $results; } I suppose one thing to be careful of it not to pass a $basedir value to this function when calling it... mostly just pass the $dir (or passing a filepath will work now too) and optionally $recursive as false if and as needed. The result: [0] => demo-image.png [1] => filelist.php [2] => tile.png [3] => 2015\header.png [4] => 2015\08\background.jpg Enjoy! Okay, back to the program I'm actually using this in... UPDATE Added extra argument for including directories in the file list or not (remembering other arguments will need to be passed to use this.) eg. $results = get_filelist_as_array($dir, true, '', true);
This solution did the job for me. The RecursiveIteratorIterator lists all directories and files recursively but unsorted. The program filters the list and sorts it. I'm sure there is a way to write this shorter; feel free to improve it. It is just a code snippet. You may want to pimp it to your purposes. <?php $path = '/pth/to/your/directories/and/files'; // an unsorted array of dirs & files $files_dirs = iterator_to_array( new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),RecursiveIteratorIterator::SELF_FIRST) ); echo '<html><body><pre>'; // create a new associative multi-dimensional array with dirs as keys and their files $dirs_files = array(); foreach($files_dirs as $dir){ if(is_dir($dir) AND preg_match('/\/\.$/',$dir)){ $d = preg_replace('/\/\.$/','',$dir); $dirs_files[$d] = array(); foreach($files_dirs as $file){ if(is_file($file) AND $d == dirname($file)){ $f = basename($file); $dirs_files[$d][] = $f; } } } } //print_r($dirs_files); // sort dirs ksort($dirs_files); foreach($dirs_files as $dir => $files){ $c = substr_count($dir,'/'); echo str_pad(' ',$c,' ', STR_PAD_LEFT)."$dir\n"; // sort files asort($files); foreach($files as $file){ echo str_pad(' ',$c,' ', STR_PAD_LEFT)."|_$file\n"; } } echo '</pre></body></html>'; ?>
This will print the full path of all files in the given directory, you can also pass other callback functions to recursiveDir. function printFunc($path){ echo $path."<br>"; } function recursiveDir($path, $fileFunc, $dirFunc){ $openDir = opendir($path); while (($file = readdir($openDir)) !== false) { $fullFilePath = realpath("$path/$file"); if ($file[0] != ".") { if (is_file($fullFilePath)){ if (is_callable($fileFunc)){ $fileFunc($fullFilePath); } } else { if (is_callable($dirFunc)){ $dirFunc($fullFilePath); } recursiveDir($fullFilePath, $fileFunc, $dirFunc); } } } } recursiveDir($dirToScan, 'printFunc', 'printFunc');
This is a little modification of majicks answer. I just changed the array structure returned by the function. From: array() => { [0] => "test/test.txt" } To: array() => { 'test/test.txt' => "test.txt" } /** * #param string $dir * #param bool $recursive * #param string $basedir * * #return array */ function getFileListAsArray(string $dir, bool $recursive = true, string $basedir = ''): array { if ($dir == '') { return array(); } else { $results = array(); $subresults = array(); } if (!is_dir($dir)) { $dir = dirname($dir); } // so a files path can be sent if ($basedir == '') { $basedir = realpath($dir) . DIRECTORY_SEPARATOR; } $files = scandir($dir); foreach ($files as $key => $value) { if (($value != '.') && ($value != '..')) { $path = realpath($dir . DIRECTORY_SEPARATOR . $value); if (is_dir($path)) { // do not combine with the next line or.. if ($recursive) { // ..non-recursive list will include subdirs $subdirresults = self::getFileListAsArray($path, $recursive, $basedir); $results = array_merge($results, $subdirresults); } } else { // strip basedir and add to subarray to separate file list $subresults[str_replace($basedir, '', $path)] = $value; } } } // merge the subarray to give the list of files then subdirectory files if (count($subresults) > 0) { $results = array_merge($subresults, $results); } return $results; } Might help for those having the exact same expected results like me.
To whom needs list files first than folders (with alphabetical older). Can use following function. This is not self calling function. So you will have directory list, directory view, files list and folders list as seperated array also. I spend two days for this and do not want someone will wast his time for this also, hope helps someone. function dirlist($dir){ if(!file_exists($dir)){ return $dir.' does not exists'; } $list = array('path' => $dir, 'dirview' => array(), 'dirlist' => array(), 'files' => array(), 'folders' => array()); $dirs = array($dir); while(null !== ($dir = array_pop($dirs))){ if($dh = opendir($dir)){ while(false !== ($file = readdir($dh))){ if($file == '.' || $file == '..') continue; $path = $dir.DIRECTORY_SEPARATOR.$file; $list['dirlist_natural'][] = $path; if(is_dir($path)){ $list['dirview'][$dir]['folders'][] = $path; // Bos klasorler while icerisine tekrar girmeyecektir. Klasorun oldugundan emin olalım. if(!isset($list['dirview'][$path])){ $list['dirview'][$path] = array(); } $dirs[] = $path; //if($path == 'D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-content\upgrade'){ press($path); press($list['dirview']); die; } } else{ $list['dirview'][$dir]['files'][] = $path; } } closedir($dh); } } // if(!empty($dirlist['dirlist_natural'])) sort($dirlist['dirlist_natural'], SORT_LOCALE_STRING); // delete safe ama gerek kalmadı. if(!empty($list['dirview'])) ksort($list['dirview']); // Dosyaları dogru sıralama yaptırıyoruz. Deniz P. - info[at]netinial.com foreach($list['dirview'] as $path => $file){ if(isset($file['files'])){ $list['dirlist'][] = $path; $list['files'] = array_merge($list['files'], $file['files']); $list['dirlist'] = array_merge($list['dirlist'], $file['files']); } // Add empty folders to the list if(is_dir($path) && array_search($path, $list['dirlist']) === false){ $list['dirlist'][] = $path; } if(isset($file['folders'])){ $list['folders'] = array_merge($list['folders'], $file['folders']); } } //press(array_diff($list['dirlist_natural'], $list['dirlist'])); press($list['dirview']); die; return $list; } will output something like this. [D:\Xampp\htdocs\exclusiveyachtcharter.localhost] => Array ( [files] => Array ( [0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\.htaccess [1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\index.php [2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\license.txt [3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\php.php [4] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\readme.html [5] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-activate.php [6] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-blog-header.php [7] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-comments-post.php [8] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config-sample.php [9] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config.php [10] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-cron.php [11] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-links-opml.php [12] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-load.php [13] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-login.php [14] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-mail.php [15] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-settings.php [16] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-signup.php [17] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-trackback.php [18] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\xmlrpc.php ) [folders] => Array ( [0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql [1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-admin [2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-content [3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-includes ) ) dirview output [dirview] => Array ( [0] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\.htaccess [1] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\index.php [2] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\license.txt [3] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\php.php [4] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\readme.html [5] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-activate.php [6] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-blog-header.php [7] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-comments-post.php [8] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config-sample.php [9] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-config.php [10] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-cron.php [11] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-links-opml.php [12] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-load.php [13] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-login.php [14] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-mail.php [15] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-settings.php [16] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-signup.php [17] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\wp-trackback.php [18] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\xmlrpc.php [19] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost [20] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql\exclusiv_excluwl.sql [21] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql\exclusiv_excluwl.sql.zip [22] => D:\Xampp\htdocs\exclusiveyachtcharter.localhost\exclusiv_excluwlsql )
#A-312's solution may cause memory problems as it may create a huge array if /xampp/htdocs/WORK contains a lot of files and folders. If you have PHP 7 then you can use Generators and optimize PHP's memory like this: function getDirContents($dir) { $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { yield $path; } else if($value != "." && $value != "..") { yield from getDirContents($path); yield $path; } } } foreach(getDirContents('/xampp/htdocs/WORK') as $value) { echo $value."\n"; } yield from
Ready for copy and paste function for common use cases, improved/extended version of one answer above: function getDirContents(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array { $results = []; $scanAll = scandir($dir); sort($scanAll); $scanDirs = []; $scanFiles = []; foreach($scanAll as $fName){ if ($fName === '.' || $fName === '..') { continue; } $fPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath($dir . '/' . $fName)); if (strlen($excludeRegex) > 0 && preg_match($excludeRegex, $fPath . (is_dir($fPath) ? '/' : ''))) { continue; } if (is_dir($fPath)) { $scanDirs[] = $fPath; } elseif ($onlyFiles >= 0) { $scanFiles[] = $fPath; } } foreach ($scanDirs as $pDir) { if ($onlyFiles <= 0) { $results[] = $pDir; } if ($maxDepth !== 0) { foreach (getDirContents($pDir, $onlyFiles, $excludeRegex, $maxDepth - 1) as $p) { $results[] = $p; } } } foreach ($scanFiles as $p) { $results[] = $p; } return $results; } And if you need relative paths: function updateKeysWithRelPath(array $paths, string $baseDir, bool $allowBaseDirPath = false): array { $results = []; $regex = '~^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath($baseDir)), '~') . '(?:/|$)~s'; $regex = preg_replace('~/~', '/(?:(?!\.\.?/)(?:(?!/).)+/\.\.(?:/|$))?(?:\.(?:/|$))*', $regex); // limited to only one "/xx/../" expr if (DIRECTORY_SEPARATOR === '\\') { $regex = preg_replace('~/~', '[/\\\\\\\\]', $regex) . 'i'; } foreach ($paths as $p) { $rel = preg_replace($regex, '', $p, 1); if ($rel === $p) { throw new \Exception('Path relativize failed, path "' . $p . '" is not within basedir "' . $baseDir . '".'); } elseif ($rel === '') { if (!$allowBaseDirPath) { throw new \Exception('Path relativize failed, basedir path "' . $p . '" not allowed.'); } else { $results[$rel] = './'; } } else { $results[$rel] = $p; } } return $results; } function getDirContentsWithRelKeys(string $dir, int $onlyFiles = 0, string $excludeRegex = '~/\.git/~', int $maxDepth = -1): array { return updateKeysWithRelPath(getDirContents($dir, $onlyFiles, $excludeRegex, $maxDepth), $dir); } This version solves/improves: warnings from realpath when PHP open_basedir does not cover the .. directory. does not use reference for the result array allows to exclude directories and files allows to list files/directories only allows to limit the search depth it always sort output with directories first (so directories can be removed/emptied in reverse order) allows to get paths with relative keys heavy optimized for hundred of thousands or even milions of files write for more in the comments :) Examples: // list only `*.php` files and skip .git/ and the current file $onlyPhpFilesExcludeRegex = '~/\.git/|(?<!/|\.php)$|^' . preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', realpath(__FILE__)), '~') . '$~is'; $phpFiles = getDirContents(__DIR__, 1, $onlyPhpFilesExcludeRegex); print_r($phpFiles); // with relative keys $phpFiles = getDirContentsWithRelKeys(__DIR__, 1, $onlyPhpFilesExcludeRegex); print_r($phpFiles); // with "include only" regex to include only .html and .txt files with "/*_mails/en/*.(html|txt)" path '~/\.git/|^(?!.*/(|' . '[^/]+_mails/en/[^/]+\.(?:html|txt)' . ')$)~is'
If you're using Laravel you can use the allFiles method on the Storage facade to recursively get all files as shown in the docs here: https://laravel.com/docs/8.x/filesystem#get-all-files-within-a-directory. use Illuminate\Support\Facades\Storage; class TestClass { public function test() { // Gets all the files in the 'storage/app' directory. $files = Storage::allFiles(storage_path('app')) } }
Here is mine : function recScan( $mainDir, $allData = array() ) { // hide files $hidefiles = array( ".", "..", ".htaccess", ".htpasswd", "index.php", "php.ini", "error_log" ) ; //start reading directory $dirContent = scandir( $mainDir ) ; foreach ( $dirContent as $key => $content ) { $path = $mainDir . '/' . $content ; // if is readable / file if ( ! in_array( $content, $hidefiles ) ) { if ( is_file( $path ) && is_readable( $path ) ) { $allData[] = $path ; } // if is readable / directory // Beware ! recursive scan eats ressources ! else if ( is_dir( $path ) && is_readable( $path ) ) { /*recursive*/ $allData = recScan( $path, $allData ) ; } } } return $allData ; }
here I have example for that List all the files and folders in a Directory csv(file) read with PHP recursive function <?php /** List all the files and folders in a Directory csv(file) read with PHP recursive function */ function getDirContents($dir, &$results = array()){ $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(!is_dir($path)) { $results[] = $path; } else if($value != "." && $value != "..") { getDirContents($path, $results); //$results[] = $path; } } return $results; } $files = getDirContents('/xampp/htdocs/medifree/lab');//here folder name where your folders and it's csvfile; foreach($files as $file){ $csv_file =$file; $foldername = explode(DIRECTORY_SEPARATOR,$file); //using this get your folder name (explode your path); print_r($foldername); if (($handle = fopen($csv_file, "r")) !== FALSE) { fgetcsv($handle); while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); for ($c=0; $c < $num; $c++) { $col[$c] = $data[$c]; } } fclose($handle); } } ?> http://myphpinformation.blogspot.in/2016/05/list-all-files-and-folders-in-directory-csv-file-read-with-php-recursive.html
I improved with one check iteration the good code of Hors Sujet to avoid including folders in the result array: function getDirContents($dir, &$results = array()){ $files = scandir($dir); foreach($files as $key => $value){ $path = realpath($dir.DIRECTORY_SEPARATOR.$value); if(is_dir($path) == false) { $results[] = $path; } else if($value != "." && $value != "..") { getDirContents($path, $results); if(is_dir($path) == false) { $results[] = $path; } } } return $results; }
I found this simple code: https://stackoverflow.com/a/24981012 $Directory = new RecursiveDirectoryIterator($path); $Iterator = new RecursiveIteratorIterator($Directory); //Filter to get only PDF, JPEG, JPG, GIF, TIF files. $Regex = new RegexIterator($Iterator, '/^.+(.jpe?g|.gif|.png|.tif|.pdf)$/i', RecursiveRegexIterator::GET_MATCH); foreach($Regex as $val => $Regex){ echo "$val\n<br>"; }
Finding empty folders recursively and delete them recursively
I have an directory tree which has been passed to array. I would like to there empty folders inside this array. How can I determine empty folders like /wp-content/uploads/2014/02/ and /wp-content/uploads/2014/. How can I delete them recursively. Here is my array array ( 0 => './do-update.php', 5 => './wp-config.php', 6 => './wp-content/', 7 => './wp-content/uploads/', 8 => './wp-content/uploads/2013/', 9 => './wp-content/uploads/2013/05/', 10 => './wp-content/uploads/2013/05/kabeduvarkad-1024x768.jpg', 26 => './wp-content/uploads/2013/05/kabeduvarkad2.jpg', 27 => './wp-content/uploads/2013/10/', 28 => './wp-content/uploads/2014/', 29 => './wp-content/uploads/2014/02/', 30 => './wp-content/uploads/de.php', 31 => './wp-update.tar.gz', 32 => './wp-update/', 33 => './wp-update/wp-update.tar', ) Thank you very much to Andresch Serj for him effords. Who wants to delete empty folders recursively with performance, you can use this solution. function list_directory($dir) { $file_list = array(); $stack[] = $dir; while ($stack) { $current_dir = array_pop($stack); if ($dh = opendir($current_dir)){ while (($file = readdir($dh)) !== false) { if ($file !== '.' AND $file !== '..') { $current_file = "{$current_dir}/{$file}"; $report = array(); if (is_file($current_file)) { $file_list[] = "{$current_dir}/{$file}"; } elseif (is_dir($current_file)) { $stack[] = $current_file; $file_list[] = "{$current_dir}/{$file}/"; } } } } } sort($file_list, SORT_LOCALE_STRING); return $file_list; } function remove_emptyfolders($array_filelist){ $files = array(); $folders = array(); foreach($array_filelist as $path){ // better performance for is_dir function if ($path[strlen($path)-1] == '/'){ // check for last character if it is / which is a folder. $folders[] = $path; } else{ $files[] = $path; } } // bos olmayan klasorleri buluyoruz. // eger klasor ismi dosya isimlerinin icerisinde gecmiyorsa bos demektir? right? $folders_notempty = array(); foreach($files as $file){ foreach($folders as $folder){ if(strpos($file,$folder) !== false){ // dublicate olmasin diye key isimlerinin ismine yazdırdık. $folders_notempty[$folder] = $folder; } } } // bos olmayanla klasorleri, digerlerinden cikariyoruz. $folders_empty = array(); foreach($folders as $folder){ // eger bos olmayanlarin icerisinde bu dosya yoksa if(!in_array($folder, $folders_notempty)){ $folders_empty[] = $folder; } } // once en uzaktan silmeye baslamaliyiz. kisaca tersten. $folders_empty = array_reverse($folders_empty); $folders_deleted = array(); foreach($folders_empty as $k){ try{ $folders_deleted[$k] = 'NOT Succesfull'; if(rmdir($k)){ $folders_deleted[$k] = 'Deleted'; continue; } chmod($k, 0777); if(rmdir($k)){ $folders_deleted[$k] = 'Deleted after chmod'; } }catch (Exception $e) { print_r($e); } } return $folders_deleted; } $files = list_directory(getcwd()); //print_r($files); $files_deleted = remove_emptyfolders($files); print_r($files_deleted);
Simply iterate over your array using foreach. foreach ($filesArray as $file) { Then for each file, check if it is a folder using is_dir like this if (is_dir ($file)) { If it is a folder/directory, read the directory, for instanse using scandir. $directoryContent = scandir($file); If the result of scandir is empty, you have an empty folder that you can delete with unlink. if (count($directoryContent) <= 2) { // checkig if there is moire than . and .. unlink($file); If you have trouble with unlink, you may have to set file permissions accordingly. If instead you need a function that recursively deletes empty subfolders given some paht, you should consider reading the SO question that was linkes in the comments. EDIT After taking into consideration your comments, what you do want is a function that deletes parent folders as well. So for a geiven level1/level2/level3 where level3 is empty and the only folder/file in level2 you want level2 to be deleted as well. So from your example array, you want ./wp-content/uploads/2014/ deleted and not just ./wp-content/uploads/2014/10, but only if ./wp-content/uploads/2014/10 has no content or subfolders with content. So how to do that? Simle: Extend your check for weather that folder is empty. If it is empty, manipoulate the given file/path string to get the parent folder. By now you should outsource this to a recursive functions indeed. function doesDirectoryOnlyContainEmptyFolders($path) { if(is_dir($path) { $directoryContent = scandir($path); if (count($directoryContent) <= 2) { return true; } else { foreach ($directoryContent as $subPath) { if($filePath !== '.' && $filePath !== '..' && !doesDirectoryOnlyContainEmptyFolders($subPath)) { return false; } } return true; } } return false; } So this function checks recursively if a path has only empty folders or folders containing empty folders - recursively. Now you want to check your paths and maybe delete them, recursively downwards and upwards. function deleteEmptyFoldersRecursivelyUpAndDown($path) { if (is_dir($path)) { if(doesDirectoryOnlyContainEmptyFolders($path)) { unlink($path); $parentFolder = substr($path, 0, strripos ($path, '/')); deleteEmptyFoldersRecursivelyUpAndDown($parentFolder); } else { $directoryContent = scandir($path); foreach ($directoryContent as $subPath) { deleteEmptyFoldersRecursivelyUpAndDown($subPath); } } } } If the given path is a directory, we check if it is empty using our recursive function. If it is, we delete it and recursively check the parent directory. If it is not, we iterate over its content to find empty folders, again calling the function itself recursively. With these two function you have all you need. Simply iterate over your path array and use deleteEmptyFoldersRecursivelyUpAndDownon all entries. If they are faulty, you'll manage to debug them i presume.
Delete the unwanted files and folders from destination folder as compared to source folder
I am using PHP and I need to script something like below: I have to compare two folder structure and with reference of source folder I want to delete all the files/folders present in other destination folder which do not exist in reference source folder, how could i do this? EDITED: $original = scan_dir_recursive('/var/www/html/copy2'); $mirror = scan_dir_recursive('/var/www/html/copy1'); function scan_dir_recursive($dir) { $all_paths = array(); $new_paths = scandir($dir); foreach ($new_paths as $path) { if ($path == '.' || $path == '..') { continue; } $path = $dir . DIRECTORY_SEPARATOR . $path; if (is_dir($path)) { $all_paths = array_merge($all_paths, scan_dir_recursive($path)); } else { $all_paths[] = $path; } } return $all_paths; } foreach($mirror as $mirr) { if($mirr != '.' && $mirr != '..') { if(!in_array($mirr, $original)) { unlink($mirr); // delete the file } } } The above code shows what i did.. Here My copy1 folder contains extra files than copy2 folders hence i need these extra files to be deleted. EDITED: Below given output is are arrays of original Mirror and of difference of both.. Original Array ( [0] => /var/www/html/copy2/Copy (5) of New Text Document.txt [1] => /var/www/html/copy2/Copy of New Text Document.txt ) Mirror Array ( [0] => /var/www/html/copy1/Copy (2) of New Text Document.txt [1] => /var/www/html/copy1/Copy (3) of New Text Document.txt [2] => /var/www/html/copy1/Copy (5) of New Text Document.txt ) Difference Array ( [0] => /var/www/html/copy1/Copy (2) of New Text Document.txt [1] => /var/www/html/copy1/Copy (3) of New Text Document.txt [2] => /var/www/html/copy1/Copy (5) of New Text Document.txt ) when i iterate a loop to delete on difference array all files has to be deleted as per displayed output.. how can i rectify this.. the loop for deletion is given below. $dirs_to_delete = array(); foreach ($diff_path as $path) { if (is_dir($path)) { $dirs_to_delete[] = $path; } else { unlink($path); } } while ($dir = array_pop($dirs_to_delete)) { rmdir($dir); }
First you need a recursive listing of both directories. A simple function like this will work: function scan_dir_recursive($dir, $rel = null) { $all_paths = array(); $new_paths = scandir($dir); foreach ($new_paths as $path) { if ($path == '.' || $path == '..') { continue; } if ($rel === null) { $path_with_rel = $path; } else { $path_with_rel = $rel . DIRECTORY_SEPARATOR . $path; } $full_path = $dir . DIRECTORY_SEPARATOR . $path; $all_paths[] = $path_with_rel; if (is_dir($full_path)) { $all_paths = array_merge( $all_paths, scan_dir_recursive($full_path, $path_with_rel) ); } } return $all_paths; } Then you can compute their difference with array_diff. $diff_paths = array_diff( scan_dir_recursive('/foo/bar/mirror'), scan_dir_recursive('/qux/baz/source') ); Iterating over this array, you will be able to start deleting files. Directories are a bit trickier because they must be empty first. // warning: test this code yourself before using on real data! $dirs_to_delete = array(); foreach ($diff_paths as $path) { if (is_dir($path)) { $dirs_to_delete[] = $path; } else { unlink($path); } } while ($dir = array_pop($dirs_to_delete)) { rmdir($dir); } I've tested things and it should be working well now. Of course, don't take my word for it. Make sure to setup your own safe test before deleting real data.
For recursive directories please use: $modified_directory = new RecursiveIteratorIterator( new RecursiveDirectoryIterator('path/to/modified'), true ); $modified_files = array(); foreach ($modified_directory as $file) { $modified_files []= $file->getPathname(); } You can do other things like $file->isDot(), or $file->isFile(). For more file commands with SPLFileInfo visit http://www.php.net/manual/en/class.splfileinfo.php
Thanks all for the precious time given to my work, Special Thanks to erisco for his dedication for my problem, Below Code is the perfect code to acomplish the task I was supposed to do, with a little change in the erisco's last edited reply... $source = '/var/www/html/copy1'; $mirror = '/var/www/html/copy2'; function scan_dir_recursive($dir, $rel = null) { $all_paths = array(); $new_paths = scandir($dir); foreach ($new_paths as $path) { if ($path == '.' || $path == '..') { continue; } if ($rel === null) { $path_with_rel = $path; } else { $path_with_rel = $rel . DIRECTORY_SEPARATOR . $path; } $full_path = $dir . DIRECTORY_SEPARATOR . $path; $all_paths[] = $path_with_rel; if (is_dir($full_path)) { $all_paths = array_merge( $all_paths, scan_dir_recursive($full_path, $path_with_rel) ); } } return $all_paths; } $diff_paths = array_diff( scan_dir_recursive($mirror), scan_dir_recursive($source) ); echo "<pre>Difference ";print_r($diff_paths); $dirs_to_delete = array(); foreach ($diff_paths as $path) { $path = $mirror."/".$path;//added code to unlink. if (is_dir($path)) { $dirs_to_delete[] = $path; } else { if(unlink($path)) { echo "File ".$path. "Deleted."; } } } while ($dir = array_pop($dirs_to_delete)) { rmdir($dir); }
First do a scandir() of the original folder, then do a scandir on mirror folder. start traversing the mirror folder array and check if that file is present in the scandir() of original folder. something like this $original = scandir('path/to/original/folder'); $mirror = scandir('path/to/mirror/folder'); foreach($mirror as $mirr) { if($mirr != '.' && $mirr != '..') { if(in_array($mirr, $original)) { // do not delete the file } else { // delete the file unlink($mirr); } } } this should solve your problem. you will need to modify the above code accordingly (include some recursion in the above code to check if the folder that you are trying to delete is empty or not, if it is not empty then you will first need to delete all the file/folders in it and then delete the parent folder).
Get the hierarchy of a directory with PHP
I'm trying to find all the files and folders under a specified directory For example I have /home/user/stuff I want to return /home/user/stuff/folder1/image1.jpg /home/user/stuff/folder1/image2.jpg /home/user/stuff/folder2/subfolder1/image1.jpg /home/user/stuff/image1.jpg Hopefully that makes sense!
function dir_contents_recursive($dir) { // open handler for the directory $iter = new DirectoryIterator($dir); foreach( $iter as $item ) { // make sure you don't try to access the current dir or the parent if ($item != '.' && $item != '..') { if( $item->isDir() ) { // call the function on the folder dir_contents_recursive("$dir/$item"); } else { // print files echo $dir . "/" .$item->getFilename() . "<br>"; } } } }
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir)) as $f) { echo "$f \r\n"; }
The working solution (change with your folder name) <?php $path = realpath('yourfolder/subfolder'); ## or use like this ## $path = '/home/user/stuff/folder1'; foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) { echo "$filename\n"; } ?>
$dir = "/home/user/stuff/"; $scan = scandir($dir); foreach ($scan as $output) { echo "$output" . "<br />"; }
Find all the files and folders under a specified directory. function getDirRecursive($dir, &$output = []) { $scandir = scandir($dir); foreach ($scandir as $a => $name) { $path = realpath($dir . DIRECTORY_SEPARATOR . $name); if (!is_dir($path)) { $output[] = $path; } else if ($name != "." && $name != "..") { getDirRecursive($path, $output); $output[] = $path; } } return $output; } var_dump(getDirRecursive('/home/user/stuff')); Output (example) : array (size=4) 0 => string '/home/user/stuff/folder1/image1.jpg' (length=35) 1 => string '/home/user/stuff/folder1/image2.jpg' (length=35) 2 => string '/home/user/stuff/folder2/subfolder1/image1.jpg' (length=46) 3 => string '/home/user/stuff/image1.jpg' (length=27)
listAllFiles( '../cooktail/' ); //send directory path to get the all files and floder of root dir function listAllFiles( $strDir ) { $dir = new DirectoryIterator( $strDir ); foreach( $dir as $fileinfo ) { if( $fileinfo == '.' || $fileinfo == '..' ) continue; if( $fileinfo->isDir() ) { listAllFiles( "$strDir/$fileinfo" ); } echo $fileinfo->getFilename() . "<br/>"; } }
Beside RecursiveDirectoryIterator solution there is also glob() solution: // do some extra filtering here, if necessary function recurse( $item ) { return is_dir( $item ) ? array_map( 'recurse', glob( "$item/*" ) ) : $item; }; // array_walk_recursive: any key that holds an array will not be passed to the function. array_walk_recursive( ( recurse( 'home/user/stuff' ) ), function( $item ) { print_r( $item ); } );
You can use the RecursiveDirectoryIterator or even the glob function. Alternatively, the scandir function will do the job.