0

I am trying to build a recursive function but in some way function doesnt display all the directories.What am I missing? I know that i could use for or while, but i want foreach loop. Here is the code:

$GLOBALS['testmodus']=0;
$o=new BrowseFolder();
$o->browse('../images/',1);
ta($o);
function ta($ausgabe) {
  echo('<p class="ta">'.__LINE__.$ausgabe.'</p>');
 }


class BrowseFolder{
    private $srcFolder;
    private $ifRecursiv=0;
    private $excludeFileTypes=array('.','..');
    private $filesFound;
    private $deleteFolderPath=0;
    private $makeFolderPath;

    public function browse($srcFolder,$ifRecursiv=0){
        ta($this->filesFound);
        $this->srcFolder=$srcFolder;
        $this->ifRecursiv=$ifRecursiv;
        $this->filesFound=scandir($this->srcFolder);
        $this->filesFound=$this->excludeArrayFromArray($this->filesFound,$this->excludeFileTypes);
        echo "<ul>";
        foreach($this->filesFound as $val){
                if(is_file($this->srcFolder.$val)){
                    echo "<li>";
                    echo "$val";
                    echo "</li>";
                    }elseif(is_dir($this->srcFolder.$val) && $this->ifRecursiv==1){
                        ta($this->srcFolder.$val);
                        echo "$val";
                        $this->browse($this->srcFolder.$val.'/',$this->ifRecursiv);

                      }
        }
        echo "</ul>";
    }

    private function excludeArrayFromArray($baseArray,$arrayToExclude){  //Exclude an array from another array,and arrange
        $newArray=array_values(array_diff($baseArray,$arrayToExclude));  
        return $newArray;

    }
}
9
  • 2
    Could you add abit more about in what way it does not go through all folders. Also have you considered using DirectoryIterator? php.net/manual/en/class.directoryiterator.php Commented Oct 20, 2013 at 20:56
  • 1
    @Ronni Skansing - probably want the recursive version: php.net/manual/en/class.recursivedirectoryiterator.php Commented Oct 20, 2013 at 21:03
  • Thanks, @Ronni Skansing.For learning purpose i prefer to use my code,and not the DirectoryIterator. I have two folders with some images. The first is showing up(with other subfolders), the last one is 'eliminated' Commented Oct 20, 2013 at 21:04
  • With only two it's hard to see which issue is actually occurring: skipping the last or only taking the first. Add a third dummy folder with some fake files and see what the result is. Commented Oct 20, 2013 at 21:07
  • Your function will produce invalid HTML, because when it goes into a sub-directory it outputs another ul – that will not be encapsulated within an li, so it will end up as a direct child of the parent ul … but as we all (should) know, ul can have only li as child elements. Commented Oct 20, 2013 at 21:10

1 Answer 1

1

I'm going to guess that if you looked at the web server log, you'd see this error:

PHP Catchable fatal error:  Object of class BrowseFolder could not be converted to string in <filename> on line <XX>

Your BrowseFolder class has no __toString() method, so an attempt to call it in string context is throwing a fatal error (this line: ta($o);)

However, that's only problem 1. Problem 2 is this:

$this->srcFolder=$srcFolder;

Since there's only a single instance of your BrowseFolder class, you're setting a property on the class and then attempting to reuse that in recursion. So basically what it's doing is drilling into the first folder, then since $this->srcFolder just equals subsequent children of that, it makes no attempts to go further. Replace every instance of $this->srcFolder with just $srcFolder. The recursive function will then drill down into the first, then when it reaches the end, work its way back up to the first call of browse(), then continue onto the second, and so on.

Edit - additional detail: It shouldn't be modifying the variable each time. What it's doing is taking the first folder images, then setting that property on the class. It goes down into the first child of that folder - call it folder1, then again sets the class property to that child (i.e. $this->srcFolder == "images/folder1"). It lists the files in that folder, then continues on. Since there are no more files or subdirectories in that folder, it's reached the end of that iteration. So then it goes back up a level to the images folder. It goes to the next iteration of the foreach loop and now sets $val to folder2. Now it tries both if(is_file($this->srcFolder.$val)) and else if (is_dir($this->srcFolder.$val). The translation of that is is_file("images/folder1/folder2") since $this->srcFolder equals images/folder1. As a result, this always returns false until it just reaches the end of the foreach and exits.

If you instead call $srcFolder (local variable), then it will have the correct value each time it gets to the function. In the same scenario: it goes into folder1 and just inside the second level of the browse() function, $srcFolder == "images/folder1". It lists each element of that folder, then goes back up to images. Now the function still has its initial value for $srcFolder, which is "images". So then in the second iteration of the foreach loop, now $val again equals folder2, so it calls browse() on that. Again in the second level of the function, $srcFolder == "images/folder2". Using a local variable in recursion ensures that each call of the function will have the value it needs.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks,@ChicagoRedSox. The first problem is saw it.Was only a check-up function. The second one...Well, i think my function is modyfing the $srcFolder class variable every time is changing the path. So, why isn't working?
I think the problem reside in this code: $this->srcFolder.$val .I think srcFolder.$val tries to concatenate and then resolve $this. Something like that: ($this->)srcFolder.$val. Or? @ChicagoRedSox
See my long addition to the answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.