main folder is home - with subfolders and txt files - on various levels
I need the list of entire folders tree - and count txt files inside each of them
This code gives the folders but count is always - 0
I suppose paths to folders and not only folder names - are required, but can't see - how to get them.
function rscan ($dir) {
$all = array_diff(scandir($dir), [".", ".."]);
foreach ($all as $ff) {
if(is_dir($dir . $ff)){
echo $ff . "\n"; // it works
$arr = glob($ff . "/*.txt");
echo count($arr) . "\n"; // always 0
rscan("$dir$ff/");
}
}
}
rscan("home/");
Line 6
$arr = glob($ff . "/*.txt");
Change to the code below:
$arr = glob($dir.$ff . "/*.txt");
An alternate implementation:
<?php
function glob_recursive($pattern, $flags = 0): Int {
$files = glob($pattern, $flags);
$count = count($files);
foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
$count += glob_recursive($dir.'/'.basename($pattern), $flags);
}
return $count;
}
var_dump(glob_recursive('home/*.txt'));
The output is something like:
int(10)
Related
I have a directory that has some file names. I want to get all the files in that directory which contains substring.
MyDir =>
- Hello12.pdf
- ABC.pdf
- hello.pdf
- JohnDoe.pdf
- hello33.pdf
I want to give 'Hello' and get all the filenames containing Hello with their extension; and get result like ['Hello12.pdf', 'hello.pdf, 'hello33.pdf']
$dir = public_path('files/MyDir');
How can I get the files in an array containing 'Hello' substring in their filename in MyDir directory?
Is going from this way a good approach?
foreach(glob($dir . '/*.pdf') as $filename){
var_dump($filename);
}
You can use scandir method to get all file names. then iterate through it and find matches
$dir = public_path('files/MyDir');
$files = scandir ($dir);
$match = "Hello";
$match_files = array();
foreach ($files as $file) {
if((stripos($file, $match) !== false)
$match_files[]=$file;
}
print_r($match_files);
first you need to scan dir and then find the string and add them to array
<?php
$i = scandir(__DIR__ . '/files/MyDir', 1);
$array = [];
foreach ($i as $x) {
if (strpos($x, 'hello') !== FALSE) {
$array[] = $x;
}
}
echo var_export($array, true);
I Want To Get List Of Files In My Directories & Sub-Directories In An Array In PHP Language .
I Have 2 Type Of Code :
1- First Code:
This Bellow Code List All Files In An Array , But There Are Folders And Sub-directories In Array :
$files = dir_scan('pathAddress');
function dir_scan($folder) {
$files = glob($folder);
foreach ($files as $f) {
if (is_dir($f)) {
$files = array_merge($files, dir_scan($f .'/*')); // scan subfolder
}
}
return $files;
}
echo "<pre>";
print_r($files);
echo "</pre>";
Result Of Top Code : Click For View Image
2- Second Code:
This Bellow Code List All MP3 Files But In String Not Array! & I Can't Convert It To Array.
$scan_it = new RecursiveDirectoryIterator("pathAddress");
foreach(new RecursiveIteratorIterator($scan_it) as $file) {
if (strtolower(substr($file, -4)) == ".mp3") {
echo "<pre>";
echo($file);
echo "</pre>";
}
}
Result Of Top Code : Click For View Image
Finally, I Want An Array Of MP3 Files In All Directories & Sub-Directories Specified Location .
Thanks For Your Help
This code might help you, It will check all the folders and in return, will get file names ..
<?php
function listFolderFiles($dir)
{
$file_names = array();
foreach (new DirectoryIterator($dir) as $fileInfo) {
if (!$fileInfo->isDot()) {
if ($fileInfo->isDir()) {
// checking directory empty or not, if not then append list
$isDirEmpty = !(new \FilesystemIterator($fileInfo->getPathname()))->valid();
if($isDirEmpty != 1)
{
$file_names[] = listFolderFiles($fileInfo->getPathname());
}
}
else
{
$file_names[] = $fileInfo->getPathname() ;
}
}
}
// Splicing Array
for ($i=0; $i<count($file_names); $i++) {
if (is_array($file_names[$i])) {
array_splice($file_names, $i, 1, $file_names[$i]);
}
}
return $file_names;
}
$res = listFolderFiles('main_folder_name');
echo '<pre>';
print_r($res);
?>
I have this working function that finds folders and creates an array.
function dua_get_files($path)
{
foreach (glob($path . "/*", GLOB_ONLYDIR) as $filename)
{
$dir_paths[] = $filename;
}
return $dir_paths;
}
This function can only find the directories on the current location. I want to find the directory paths in the child folders and their children and so on.
The array should still be a flat list of directory paths.
An example of how the output array should look like
$dir_path[0] = 'path/folder1';
$dir_path[1] = 'path/folder1/child_folder1';
$dir_path[2] = 'path/folder1/child_folder2';
$dir_path[3] = 'path/folder2';
$dir_path[4] = 'path/folder2/child_folder1';
$dir_path[5] = 'path/folder2/child_folder2';
$dir_path[6] = 'path/folder2/child_folder3';
If you want to recursively work on directories, you should take a look at the RecursiveDirectoryIterator.
$path = realpath('/etc');
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
echo "$name\n";
}
Very strange - everybody advice recursion, but better just cycle:
$dir ='/dir';
while($dirs = glob($dir . '/*', GLOB_ONLYDIR)) {
$dir .= '/*';
if(!$result) {
$result = $dirs;
} else {
$result = array_merge($result, $dirs);
}
}
Try this instead:
function dua_get_files($path)
{
$data = array();
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach ($files as $file)
{
if (is_dir($file) === true)
{
$data[] = strval($file);
}
}
return $data;
}
Use this function :
function dua_get_files($path)
{
$dir_paths = array();
foreach (glob($path . "/*", GLOB_ONLYDIR) as $filename)
{
$dir_paths[] = $filename;
$a = glob("$filename/*", GLOB_ONLYDIR);
if( is_array( $a ) )
{
$b = dua_get_files( "$filename/*" );
foreach( $b as $c )
{
$dir_paths[] = $c;
}
}
}
return $dir_paths;
}
You can use php GLOB function, but you must create a recursive function to scan directories at infinite level depth. Then store results in a global variable.
function dua_get_files($path) {
global $dir_paths; //global variable where to store the result
foreach ($path as $dir) { //loop the input
$dir_paths[] = $dir; //can use also "basename($dir)" or "realpath($dir)"
$subdir = glob($dir . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR); //use DIRECTORY_SEPARATOR to be OS independent
if (!empty($subdir)) { //if subdir is not empty make function recursive
dua_get_files($subdir); //execute the function again with current subdir
}
}
}
//usage:
$path = array('galleries'); //suport absolute or relative path. support one or multiple path
dua_get_files($path);
print('<pre>'.print_r($dir_paths,true).'</pre>'); //debug
For PHP, if you are on a linux/unix, you can also use backticks (shell execution) with the unix find command. Directory searching on the filesystem can take a long time and hit a loop -- the system find command is already built for speed and to handle filesystem loops. In other words, the system exec call is likely to cost far less cpu-time than using PHP itself to search the filesystem tree.
$dirs = `find $path -type d`;
Remember to sanitize the $path input, so other users don't pass in security compromising path names (like from the url or something).
To put it into an array
$dirs = preg_split("/\s*\n+\s*/",`find $path -type d`,-1,PREG_SPLIT_NO_EMPTY);
I have these files:
"id_1_1.php", "id_1_2.php", "id_1_3.php" etc
"id_2_1.php", "id_2_2.php", "id_2_3.php" etc
the number of files is not known because will always grow..
all the files are in same directory..
I want to make a if statement:
to include the files only if their name ends with "_1"
another function to load all the files that start with "id_1"
How can I do this? Thank you!
edit1: no the numbers will not be skipped, once I have another item for id_1_ collection of products I will add new ones as id_1_1, id_1_2 etc.. so no skipping..
// Each of these:
// - scans the directory for all files
// - checks each file
// - for each file, does it match the pattern described
// - if it does, expand the path
// - include the file once
function includeFilesBeginningWith($dir, $str) {
$files = scandir($dir);
foreach ($files as $file) {
if (strpos($file, $str) === 0) {
$path = $dir . '/' . $file;
include_once($path);
}
}
}
function includeFilesEndingWith($dir, $str) {
$files = scandir($dir);
foreach ($files as $file) {
if (strpos(strrev($file), strrev($str)) === 0) {
$path = $dir . '/' . $file;
include_once($path);
}
}
}
/* To use: - the first parameter is ".",
the current directory, you may want to
change this */
includeFilesBeginningWith('.', 'id_1');
includeFilesEndingWith('.', '_1.php');
Loosely based on Svisstack's original answer (untested):
function doIncludes($pre='',$post=''){
for ($i=1;1;$i++)
if (file_exists($str=$pre.$i.$post.'.php'))
include($str);
else
return;
}
function first_function(){
doIncludes('id_','_1');
}
function second_function(){
doIncludes('id_1_');
}
function my_include($f, $s)
{
#include_once("id_" . $f . "_" . $s . ".php");
}
function first_function($howmany = 100, $whatstart = '1')
{
for ($i=1; $i <= $howmany; $i++)
{
my_include('1', $i)
}
}
function second_function($howmany = 100, $whatend = '1')
{
for ($i=1; $i <= $howmany; $i++)
{
my_include($i, '1');
}
}
This will parse through every file incrementing by one until it finds a file that doesn't exist. Assuming contiguous numbers it should catch every existing file. If you want to include files with a number other then 1 in the name, just change $lookingfor as appropriate.
$lookingfor = 1;
$firstnum=1;
while ($firstnum>0) {
$secondnum=1;
while ($secondnum>0) {
$tempfilename = "id_".$firstnum."_".$secondnum.".php";
if file_exists($tempfilename) {
if (($firstnum==$lookingfor)||($secondnum==$lookingfor)) {include $tempfilename; }
$secondnum++;
} else {
$secondnum=-1;
}
}
$firstnum++;
}
I want to use a function to recursively scan a folder, and assign the contents of each scan to an array.
It's simple enough to recurse through each successive index in the array using either next() or foreach - but how to dynamically add a layer of depth to the array (without hard coding it into the function) is giving me problems. Here's some pseudo:
function myScanner($start){
static $files = array();
$files = scandir($start);
//do some filtering here to omit unwanted types
$next = next($files);
//recurse scan
//PROBLEM: how to increment position in array to store results
//$next_position = $files[][][].... ad infinitum
//myScanner($start.DIRECTORY_SEPARATOR.$next);
}
any ideas?
Try something like this:
// $array is a pointer to your array
// $start is a directory to start the scan
function myScanner($start, &$array){
// opening $start directory handle
$handle = opendir($start);
// now we try to read the directory contents
while (false !== ($file = readdir($handle))) {
// filtering . and .. "folders"
if ($file != "." && $file != "..") {
// a variable to test if this file is a directory
$dirtest = $start . DIRECTORY_SEPARATOR . $file;
// check it
if (is_dir($dirtest)) {
// if it is the directory then run the function again
// DIRECTORY_SEPARATOR here to not mix files and directories with the same name
myScanner($dirtest, $array[$file . DIRECTORY_SEPARATOR]);
} else {
// else we just add this file to an array
$array[$file] = '';
}
}
}
// closing directory handle
closedir($handle);
}
// test it
$mytree = array();
myScanner('/var/www', $mytree);
print "<pre>";
print_r($mytree);
print "</pre>";
Try to use this function (and edit it for your demands):
function getDirTree($dir,$p=true) {
$d = dir($dir);$x=array();
while (false !== ($r = $d->read())) {
if($r!="."&&$r!=".."&&(($p==false&&is_dir($dir.$r))||$p==true)) {
$x[$r] = (is_dir($dir.$r)?array():(is_file($dir.$r)?true:false));
}
}
foreach ($x as $key => $value) {
if (is_dir($dir.$key."/")) {
$x[$key] = getDirTree($dir.$key."/",$p);
}
}
ksort($x);
return $x;
}
It returns sorted array of directories.