3

For example I have a build.json file below. Contains a basic folder / file structure I made up created in JSON.

  {
    "folders": [
        {
            "name": "folder-a",
            "files": [
                {
                    "name": "file-a.html"
                },
                {
                    "name": "file-b.html"
                }
            ],
            "folders": [
                {
                    "name": "sub-folder-a",
                    "files": [
                        {
                            "name": "sub-file-a.html"
                        },
                        {
                            "name": "sub-file-b.html"
                        }
                    ]
                }
            ]
        },
        {
            "name": "folder-b",
            "files": [
                {
                    "name": "file-a.html"
                },
                {
                    "name": "file-b.html"
                }
            ]
        }
    ]
}

Now I created the simple PHP code below, which can loop through the first parts of the array. Then of course if I keep making foreach loops inside of the first foreach, I can keep going through the array. The problem is that I have no idea how many folders / files there will be in the array. Any ideas on how I can just keep looping without knowing how many times to loop? Thanks!

$json = file_get_contents('build.json');

$decode = json_decode($json);

foreach($decode as $key => $val){
    foreach($val as $valKey => $data){
        var_dump($data);
    }
}
2
  • 1
    you'll probably want to use some form of recursion unless you know the maximum level of nesting of folders. Commented Sep 29, 2015 at 2:54
  • I do not know the level of nesting. And I been Googling a lot about recursion, just unsure how to write it in a loop. Commented Sep 29, 2015 at 2:57

2 Answers 2

3

Here's a working script, using recursion:

$json = file_get_contents('build.json');
$folders = json_decode($json);

function buildDirs($folders, $path = null){
  $path = $path == null ? "" : $path . "/";

  foreach($folders as $key => $val){
     mkdir($path.$val->name);
     echo "Folder: " . $path . $val->name . "<br>";

     if(!empty($val->files)){
        foreach($val->files as $file){
           //Create the files inside the current folder $val->name
           echo "File: " . $path . $val->name . "/" . $file->name . "<br>";
           file_put_contents($path . $val->name . "/". $file->name, "your data");
        }
     }

     if(!empty($val->folders)){ //If there are any sub folders, call buildDirs again!
        buildDirs($val->folders, $path . $val->name);
     }
  }
}

buildDirs($folders->folders); //Will build from current directory, otherwise send the path without trailing slash /var/www/here

Remember to the set the right permissions to the root folder.

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

4 Comments

This created empty folder- a in the root directory of the project. Then it created file-a.html and file-b.html in the root directory of the project as well.
I just tested in my folder, eveything went perfectly. You are using the same JSON as you posted?
Fatal error: Call to undefined function buildDir() in /home/ubuntu/workspace/gen.php on line 19 Call Stack: 0.0003 253288 1. {main}() /home/ubuntu/workspace/gen.php:0 0.0004 261560 2. buildDirs() /home/ubuntu/workspace/gen.php:24 -- Maybe something to do with my php.ini settings?
Ill try to explain it a little bit more, I'll update my answer in a few.
1

I haven't tested the code below, so don't shoot me if there's a bug, but it illustrates the basic process of using a recursive function to solve this problem. We create a function that will create a folder at the current level, and add any files to it necessary. If it has subfolders, it will call itself, but pass in the path to the new subfolder level. When there are no more folders/files to process, it just stops, so you shouldn't be in danger of having infinite recursion (like an infinite loop).

/**
 * @param $path   string The base path in which $folder should be created
 * @param $folder object An object that contains the content to be saved
 */
function createFileStructure( $path, $folder ) {
    // create the current folder
    $path = $path . '/' . $folder->name;
    if ( mkdir( $path . $folder->name ) ) {
        foreach ( $folder->files as $file ) touch( $path . '/' . $file->name );
    }
    // now handle subfolders if necessary
    if ( isset( $folder->folders ) ) {
        createFileStructure( $path, $folder->folders );
    }
}

// now call the above recursive function
$path = __DIR__; // set the current directory as base
$json = file_get_contents('build.json');
createFileStructure( $path, json_decode( $json ) );

1 Comment

Warning: mkdir(): File exists in /home/ubuntu/workspace/gen.php on line 10 -- but the folders / files are not in the directory.

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.