Jump to content

scandir, recursive call prints an extra closing tag for xml install file


fero57

Recommended Posts

Hi Freaks

I created a Joomla 1.5 install.xml using scandir.  For easier orientation, folders are capitalized and blue

 

ASSETS

- index.html

- CSS

- - index.html

- - popup.css

- - default.css

- JS

- - index.html

- - form.js

CONTROLLERS

MODELS

TABLES

VIEWS

controller.php

index.php

reporter.php

 

output of the first 14 lines:

 
<filename>ASSETS</filename>
<filename>ASSETS/CSS</filename>
<filename>ASSETS/CSS/default.css</filename>
<filename>ASSETS/CSS/incident_reporter_form.css</filename>
<filename>ASSETS/CSS/index.html</filename>
<filename>ASSETS/CSS/popup.css</filename>
</filename>
<filename>ASSETS/index.html</filename>
<filename>ASSETS/JS</filename>
<filename>ASSETS/JS/incident_reporter_form.js</filename>
<filename>ASSETS/JS/index.html</filename>
</filename>
</filename>
<filename>controller.php</filename>
<filename>CONTROLLERS</filename>

 

My script

 

$allfiles = '';
function readFolders($dir )
{
global $allfiles;
 
    $files = scandir($dir);
 
    foreach($files as $f)
    {
        if($f != '.' && $f != '..')
        {
            $allfiles .= '<filename>'.$dir.'/'.$f;
            
            if(is_dir($dir.'/'.$f)) 
            {
                  $allfiles .= "</filename>\n";
                  readFolders($dir.'/'.$f);
            }
            $allfiles .= "</filename>\n";
        }
        
    }
    
$fp = fopen('xml_scandir.txt', 'w') or die('cannot open file');
fwrite($fp, $allfiles);
fclose($fp);
}
 
readFolders('com_reporter');

 

Question:

Why do I have those extra closing tags </filename> that attach outside if(is_dir) ? I would understand if the output came with empty tags, eg <filename></filename>

 

Thank you

 

Fero 

Edited by fero57
Link to comment
Share on other sites

I re-wrote the script and it worked. I also fixed the folder / filename tags.

 

$allfiles = '';
function readFolders($dir )
{
    global $allfiles;
 
    $files = scandir($dir);
 
    foreach($files as $f)
    {
        if($f != '.' && $f != '..')
        {       
            if(is_dir($dir.'/'.$f)) 
            {
                     $allfiles .= "<folder>".$dir.'/'.$f."</folder>\n";
                     readFolders($dir.'/'.$f);
            }
            else
            {
                      $allfiles .= '<filename>'.$dir.'/'.$f."</filename>\n";
            }
        }
    }
    
             $fp = fopen('xml_scandir.txt', 'w') or die('cannot open scandir.txt');
             fwrite($fp, $allfiles);
             fclose($fp);
}

 

 thanks for your time

Fero

Edited by fero57
Link to comment
Share on other sites

... but it is still a mystery for me why the original script outputs those extra closing tags when the loop goes from the deepest folder back ... and why only the closing tag, why not both, opening and closing, when I use

    $allfiles .=

before and after if(is_dir) condition.

 

Any ideas?

 

Fero

Edited by fero57
Link to comment
Share on other sites

Because of the way your function works with the recursion. Take some time to mentally step through it and you'll see. Lest assume you start it in a directory that has one sub-dir and then that dir has 1 file in it. Eg:

.
  js/
    whatever.js
So when you start the code, on the first iteration the it will:

$allfiles .= '<filename>'.$dir.'/'.$f;  //Set $allfiles to <filename>./js

if(is_dir($dir.'/'.$f)) //True
{
  $allfiles .= "</filename>\n";  //set $allfiles to <filename>./js</filename>
  readFolders($dir.'/'.$f);  //Start reading the new directory (see next block)
}
$allfiles .= "</filename>\n";
When it recurses into the next level, then it's first loop iteration will go like so:

$allfiles .= '<filename>'.$dir.'/'.$f;  //Set $allfiles to <filename>./js</filename><filename>./js/whatever.js

if(is_dir($dir.'/'.$f)) //False
{
  $allfiles .= "</filename>\n";  
  readFolders($dir.'/'.$f);  
}
$allfiles .= "</filename>\n"; //Set $allfiles to <filename>./js</filename><filename>./js/whatever.js</filename>

//Jump back up to previous level
So now since it is done with that sub directory, it jumps back up to where it was in the previous function call, and continues.

$allfiles .= '<filename>'.$dir.'/'.$f; 

if(is_dir($dir.'/'.$f)) 
{
  $allfiles .= "</filename>\n"; 
  readFolders($dir.'/'.$f);  //Jumps back to this point
}
$allfiles .= "</filename>\n"; //Continues to here and sets $allfiles to <filename>./js</filename><filename>./js/whatever.js</filename></filename>
Edited by kicken
Link to comment
Share on other sites

Hi Kicken

 

Thank you for the answer. I was going through your explanation a couple of times.  When I changed the tags, eg

 

$allfiles .= '<filename>'.$dir.'/'.$f;
            
                        $allfiles .= '<filename>'.$dir.'/'.$f;   // first reading
 
            if(is_dir($dir.'/'.$f)) 
            {
                  $allfiles .= "</filename>\n";
                  readFolders($dir.'/'.$f);
            }
            $allfiles .= "</filename_AFTER>\n";          // third reading

 

the output was

             </filename_AFTER>

             </filename_AFTER>

 

not as I expected, i.e. first reading - skip if not is_dir - second reading

 

             <filename></filename_AFTER>

             <filename></filename_AFTER>

 

I must be very slow on the uptake, I apologize.

 

Thanks

 

Fero

Link to comment
Share on other sites

 

            if(is_dir($dir.'/'.$f)) 
            {
                  $allfiles .= "</filename>\n";
                  readFolders($dir.'/'.$f);
            }
            $allfiles .= "</filename_AFTER>\n";          // third reading

 

The last line shown here is executed just before exiting the (recursed) function and is ALSO executed as soon as the recursed call returns. There should probably be an ELSE just before it since you close that tag inside the IF
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.