List of files and Folder - php

actully i get the folder and files from perticular path but its doesnt returns the value what i want.
im expecting the return value like:-
[{"filename":"19_0_0_0_0_1.jpg","RFI":19},
{"filename":"19_0_0_0_0_2.jpg","RFI":19},
{"filename":"19_20005_1_0_0_1.jpg","RFI":19},
{"filename":"19_20005_1_0_0_2.jpg","RFI":19},
{"filename":"19_20005_1_429_0_1.jpg","RFI":19},
{"filename":"19_20005_1_429_0_2.jpg","RFI":19},
{"filename":"19_20005_1_429_1_1.jpg","RFI":19},
{"filename":"19_20005_1_429_1_2.jpg","RFI":19},
{"filename":"19_20027_1_0_0_1.jpg","RFI":19}]
and its give me like this output :
[{"filename":[{"filename":"19_0_0_0_0_1.jpg","RFI":19},
{"filename":"19_0_0_0_0_2.jpg","RFI":19},
{"filename":"19_20005_1_0_0_1.jpg","RFI":19},
{"filename":"19_20005_1_0_0_2.jpg","RFI":19},
{"filename":"19_20005_1_429_0_1.jpg","RFI":19},
{"filename":"19_20005_1_429_0_2.jpg","RFI":19},
{"filename":"19_20005_1_429_1_1.jpg","RFI":19},
{"filename":"19_20005_1_429_1_2.jpg","RFI":19},
{"filename":"19_20027_1_0_0_1.jpg","RFI":19}],"RFI":19}]
this is my code:
$ldir = "D:\php\EIL_App\RFIImages";
$data = listFolderFiles($ldir,19);
print json_encode($data);
function listFolderFiles($dir,$pRFI)
{
$result = array();
foreach (new DirectoryIterator($dir) as $fileInfo){
if (!$fileInfo->isDot()){
$dataimg = $fileInfo->getFilename();
if($fileInfo->getFilename() == $pRFI){
if ($fileInfo->isDir()){
$dataimg = listFolderFiles($fileInfo->getPathname(),$pRFI);
}
array_push($result,array('filename'=>$dataimg,'RFI'=>$pRFI));
}
}
}
return $result;
}
Please give the suggestion what can i do???
Thanks in advance.

There's no need to complicate things
$prefix = 19;
$dir = "D:\php\EIL_App\RFIImages";
$data = glob("$prefix*.*",19); // it will give you array with all files matching pattern
// then you can do a loop
$arr = [];
foreach ($data as $filename) {
$arr[] = ['filename' => $filename, 'prefix' => $prefix];
}
echo json_encode($arr);
http://php.net/manual/en/function.glob.php
If you want to use iterator then use glob http://php.net/manual/en/globiterator.construct.php
Regarding your code
if ($fileInfo->isDir()) this makes no sense because it will never go to this if. It's because before you check if (!$fileInfo->isDot()){ and dot means either . or .. which applies to directories. If you want to do it recursively then you can use
Edit:
I've noticed you do some recursion if so then probably it'd be better to use ResursiveIterator
function listFolderFiles($dir, $prefix) {
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
$files = new RegexIterator($rii, "^$prefix.*", RegexIterator::GET_MATCH); // note prefix cannot have characters that are special to regex or they should be escaped
$arr = array();
foreach($files as $file) {
$arr[] = $file;
}
return $arr;
}
http://php.net/manual/en/class.recursivedirectoryiterator.php
http://php.net/manual/en/directoryiterator.isdot.php

Related

PHP - Directory browsing from recursive to iterative

Hello I am trying to make the following function iterative. It browses threw all directories and gives me all files in there.
function getFilesFromDirectory($directory, &$results = array()){
$files = scandir($directory);
foreach($files as $key => $value){
$path = realpath($directory.DIRECTORY_SEPARATOR.$value);
if(!is_dir($path)) {
$results[] = $path;
} else if($value != "." && $value != "..") {
getFilesFromDirectory($path, $results);
$results[] = $path;
}
}
return $results;
}
I am sure that it is possible to make this function iterative but I really have no approach how I can do this.
Your going to want to use a few PHP base classes to implement this.
Using a RecursiveDirectoryIterator inside of a RecursiveIteratorIterator will allow you to iterate over everything within a directory regardless of how nested.
Its worth noting when looping over the $iterator below each $item is an object of type SplFileinfo. Information on this class can be found here: http://php.net/manual/en/class.splfileinfo.php
<?php
//Iterate over a directory and add the filenames of all found children
function getFilesFromDirectory($directory){
//Return an empty array if the directory could not be found
if(!is_dir($directory)){
return array();
}
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directory)
);
$found = array();
foreach($iterator as $item){
if(method_exists($item, 'isFile') && $item->isFile()){
//Uncomment the below to exclude dot files
//if(method_exists($item, 'isDot') && $item->isDot()){
// continue;
//}
//Pathname == full file path
$found[] = $item->getPathname();
}
}
return $found;
}
An var_dump of some found files i did using this function as a test:
Hope this helps!

Dir-Content to array - exclude files with specific pattern

I would like to collect all files in a specific directory (at the moment I'm using scandir) - but only those, who do not have a special pattern.
Example:
someimage.png
someimage-150x150.png
someimage-233x333.png
someotherimage.png
someotherimage-760x543.png
someotherimage-150x50.png
In this case I would like to get someimage.png and someotherimage.png as result in my array.
How can I solve this?
To get array of filenames consisting of letters only, you can use this:
$array = array();
$handle = opendir($directory);
while ($file = readdir($handle)) {
if(preg_match('/^[A-Za-z]+\.png$/',$file)){
$array[] = $file;
}
}
The OOP way could be to use a DirectoryIterator in combination with a FilterIterator:
class FilenameFilter extends FilterIterator {
protected $filePattern;
public function __construct(Iterator $iterator , $pattern) {
parent::__construct($iterator);
$this->filePattern = $pattern;
}
public function accept() {
$currentFile = $this->current();
return (1 === preg_match($this->filePattern, $currentFile));
}
}
Usage:
$myFilter = new FilenameFilter(new DirectoryIterator('path/to/your/files'), '/^[a-z-_]*\.(png|PNG|jpg|JPG)$/i');
foreach ($myFilter as $filteredFile) {
// Only files which match your specified pattern should appear here
var_dump($filteredFile);
}
It's just an idea and the code is not tested but. Hope that helps;
$files = array(
"someimage.png",
"someimage-150x150.png",
"someimage-233x333.png",
"someotherimage.png",
"someotherimage-760x543.png",
"someotherimage-150x50.png",
);
foreach ( $files as $key => $value ) {
if ( preg_match( '#\-[0-9]+x[0-9]+\.(png|jpe?g|gif)$#', $value ) ) {
unset( $files[$key] );
}
}
echo '<xmp>' . print_r( $files, 1 ) . '</xmp>';
This regex will fill $correctFiles with all png images that don't contain dimensions (42x42 for example) in their names.
<?php
// here you get the files with scandir, or any method you want
$files = array(
'someimage.png',
'someimage-150x150.png',
'someimage-233x333.png',
'someotherimage.png',
'someotherimage-760x543.png',
'someotherimage-150x50.png'
);
$correctFiles = array(); // This will contain the correct file names
foreach ($files as $file)
if (!preg_match('/^.*-\d+x\d+\.png$/', $file)) // If the file doesn't have "NUMBERxNUMBER" in their name
$correctFiles[] = $file;
print_r($correctFiles); // Here you can do what you want with those files
If you don't want to store the names in an array (faster, less memory consumption), you can use the code below.
<?php
// here you get the files with scandir, or any method you want
$files = array(
'someimage.png',
'someimage-150x150.png',
'someimage-233x333.png',
'someotherimage.png',
'someotherimage-760x543.png',
'someotherimage-150x50.png'
);
foreach ($files as $file)
if (!preg_match('/^.*-\d+x\d+\.png$/', $file)) // If the file doesn't have "NUMBERxNUMBER" in their name
{
print_r($file); // Here you can do what you want with this file
}

Recursive function scanning a folder and storing it in an array

I am trying to make a recursive function to go through all of the folder path that I have given it in the parameters.
What I am trying to do is to store the folder tree into an array for example I have Folder1 and this folder contains 4 text files and another folder and I want the structure to be a multidimensional array like the following
Array 1 = Folder one
Array 1 = text.text.....So on so forth
I have the following function that I build but its not working as I want it too. I know that I need to check whether it is in the root directory or not but when it becomes recursive it becoems harder
function displayAllFolders($root)
{
$foldersArray = array();
$listFolderFile = scandir($root);
foreach($listFolderFile as $row)
{
if($row == "." || $row == "..")
{
continue;
}
elseif(is_dir("$root/$row") == true)
{
$foldersArray["$root/$row"] = "$row";
$folder = "$root/$row";
#$foldersArray[] = displayAllFolders("$root/$row");
}
else
{
$foldersArray[]= array("$root/$row") ;
}
}
var_dump($foldersArray);
}
Using RecursiveDirectoryIterator with RecursiveIteratorIterator this becomes rather easy, e.g.:
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
// root dir
'.',
// ignore dots
RecursiveDirectoryIterator::SKIP_DOTS
),
// include directories
RecursiveIteratorIterator::SELF_FIRST
// default is:
// RecursiveIteratorIterator::LEAVES_ONLY
//
// which would only list files
);
foreach ($it as $entry) {
/* #var $entry \SplFileInfo */
echo $entry->getPathname(), "\n";
}
Your approach isn't recursive at all.
It would be recursive if you called the same function again in case of a directory. You only make one sweep.
Have a look here:
http://php.net/manual/en/function.scandir.php
A few solutions are posted. I would advise you to start with the usercomment by mmda dot nl.
(function is named dirToArray, exactly what you are tryting to do.)
In case it will be removed, I pasted it here:
function dirToArray($dir) {
$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);
}
else {
$result[] = $value;
}
}
}
return $result;
}
Why not using PHP itself? Just have a look at the RecursiveDirectoryIterator of the standard php library (SPL).
$folders = [];
$iterator = new RecursiveDirectoryIterator(new RecursiveDirectoryIterator($directory));
iterator_apply($iterator, 'scanFolders', array($iterator, $folders));
function scanFolders($iterator, $folders) {
while ($iterator->valid()) {
if ($iterator->hasChildren()) {
scanFolders($iterator->getChildren(), $folders);
} else {
$folders[] = $iterator->current();
}
$iterator->next();
}
}

PHP - Get directory contents and info and output array

I'm working on the following but have become stumped as to how to get this to output.
I have the following which scans the directory contents, then gets the info and saves it as an array:
//SCAN THE DIRECTORY
$directories = scandir($dir);
$directinfo = array();
foreach($directories as $directory){
if ($directory === '.' or $directory === '..') continue;
if(!stat($dir.'/'.$directory)){
} else {
$filestat = stat($dir.'/'.$directory);
$directinfo[] = array(
'name' => $directory,
'modtime' => $filestat['mtime'],
'size' => $filestat['size']
);
}
}
When trying to output it however, I'm just getting single letters with a lot of breaks. Im obviously missing something here with the output loop.
foreach($directinfo as $dirInfo){
foreach($dirInfo as $drInfo){
for ($x=0; $x<=2; $x++) {
<span>"".$drInfo[$x]."<br/></span>";
}
}
}
Help is greatly appreciated. :)
You have already did everything just remove your for loop.
and try to do the following-
foreach($directinfo as $dirInfo){
foreach($dirInfo as $key=>$drInfo){
echo "<span>".$key."=>".$drInfo."<br/></span>";
}
}
I think your dealing with a 2d array, but treating it like a 3d array.
what does
foreach($directinfo as $dirInfo){
foreach($dirInfo as $drInfo){
var_dump($drInfo);
}
}
give you?
You're building a single array, dirInfo.
Php foreach takes the array first;
foreach($dirInfo as $info) {
echo "<span>" . $info['name'] . "</span>";
}
Try this function. It will return you list of all files with path.
// to list the directory structure with all sub folders and files
function getFilesList($dir)
{
$result = array();
$root = scandir($dir);
foreach($root as $value) {
if($value === '.' || $value === '..') {
continue;
}
if(is_file("$dir$value")) {
$result[] = "$dir$value";
continue;
}
if(is_dir("$dir$value")) {
$result[] = "$dir$value/";
}
foreach(getFilesList("$dir$value/") as $value)
{
$result[] = $value;
}
}
return $result;
}

Get folders with PHP glob - unlimited levels deep

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);

Categories