1

Someone asked same question 10 years ago but there is no answer to that

Reference: Trying to create Array from String (file/folder structure)


Update Jan 8, 2022: This is how array and tree should look like:

https://3v4l.org/6ULBZ#v8.1.1

The SQL output should be formed into this array structure from a string.

[
'id' => $key //Increment from foreach loop,
'file' => $row['name'] //Name of folders and files
'parent_id' => 0 // 0 - if no subfolder, $id if there is subfolder
]

I want to return a tree-level multidimensional array from file list stored in database as a string.

For example I store my work related path in database like this:

SELECT name FROM files;

... SQL Output

2021/Dec/File1.doc
2021/Dec/File2.doc
2021/Dec/File3.doc
2021/Nov/File1.doc
2021/Nov/File2.doc
2021/Nov/File3.doc
2021/Nov/File4.doc
2020/Jan/File1.doc
2020/Jan/File2.doc
2020/Jan/File3.doc

... PHP recursive array output should be categorized by folders, subfolders, more subfolders if exists and files on end.

-2021
--Dec
---File1.doc
---File2.doc
---File3.doc
--Nov
---File1.doc
---File2.doc
---File3.doc
---File4.doc
-2020
--Jan
---File1.doc
---File2.doc
---File3.doc

What would be the best way to achieve this performance wise?

What I got so far...

$files = [];
foreach ($sql as $row)
{
    // Separate directories
    $separator = explode('/', $row['name']); 
    /* Output:
    Array
    (
    [0] => 2021
    [1] => Dec
    [2] => file1.doc
    )
    */

    // Find the file via regex
    if (preg_match('/[^\/]*\.(doc|txt)/', $row['name'], $o))
    {
        $row['name'] = $o[0]; //Output: file1.doc
    }
    $files[] = $row;
}

... For now I only have a file names, now I need directories as well and then make a multidimensional array from it.

3
  • @CarySwoveland Hi. Yes, but instead of having subfolders names as array keys, I'd like to have it as parent_id => 'subfolder' and then there all the files listed. Like this: stackoverflow.com/questions/29384548/… Commented Jan 8, 2022 at 15:56
  • 1
    Added on top array and function how the string from database should be formed into array. Commented Jan 8, 2022 at 16:31
  • I assumed--which I should not have done--that PHP arrays are pretty much the same as arrays in other languages. I apologize for my unwarranted diversion. Commented Jan 8, 2022 at 16:49

2 Answers 2

1
$files = [];
foreach ($sql as $row)
{
    // Separate directories
    $separator = explode('/', $row['name']); 
    /* Output:
    Array
    (
    [0] => 2021
    [1] => Dec
    [2] => file1.doc
    )
    */

    if (preg_match('/[^\/]*\.(doc|txt)/', $row['name']))
    {
        $node = &$files;
        while (count($separator) > 1) {
            $folder = array_shift($separator);
            if (!array_key_exists($folder, $node)) {
                $node[$folder] = [];
            }
            $node = &$node[$folder];
        }
        $node[] = $separator[0];
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Hi, this is almost what I need. Can instead of having array key as folder name, to have parent_id => 'Subfolder' ? Reference: stackoverflow.com/questions/29384548/…
I've created a structure how it should look from the string which we separated into array of folders 3v4l.org/6ULBZ#v8.1.1
0

I have one solution for you, I hope this will help.

$files="2021/Dec/File1.doc, 
2021/Dec/File2.doc,
2021/Dec/File3.doc,
2021/Nov/File1.doc,
2021/Nov/File2.doc,
2021/Nov/File3.doc,
2021/Nov/File4.doc,
2020/Jan/File1.doc,
2020/Jan/File2.doc,
2020/Jan/File3.doc";

$files=explode(',',$files);

foreach($files as $file)
{
    $i=1;
    $paths=explode('/',$file);
    foreach($paths as $path)
    {
        for($j=0;$j<$i;++$j){
            echo '-';
        }
        echo $path;
        echo "<br/>";
        ++$i;
    }
    $i=0;
}

You can use your database files. by removing my files constant value and use your.

1 Comment

Thank you, but subfolders are not merged, they are all separated which defeats the purpose of the thing I need

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.