webForumDet fria alternativet

Skapa mappar rekursivt från array

PHP

6 svar · 861 visningar · startad av MickeA.com

Medlem sedan feb. 20034 441 inlägg
Frågan#1

Tjena hej!

Jag har en array som ser ut såhär:

Array
(
    [0] => Array
        (
            [Name] => Micke
            [Children] => Array
                (
                    [0] => Array
                        (
                            [Name] => Micke
                            [Children] => Array
                                (
                                    [0] => Array
                                        (
                                            [Name] => Micke
                                            [Children] => Array()
                                        )

                                    [1] => Array
                                        (
                                            [Name] => Micke
                                            [Children] => Array
							(
								[Name] => Micke
								[Children] => Array()
							)
                                        )
			)
						)
				)
		)
)

Nu ska jag skapa mappar enligt samma hierarki, men dyker på problem när någon "children" är tom. Koden:

function CreateFolders($Data = array(), $Path = ROOTPATH){
	foreach($Data as $Key => $User){
		$Path .= $User['Slug'] . "/";
		echo $Path . "<br />";
		if(sizeof($User['Children']) != 0){
			$Path .= $User['Slug'] . "/";
			CreateFolders($User['Children'], $Path);
		}
	}
}

Den ska skapa mappar nu såhär:

Micke
Micke/Micke
Micke/Micke/Micke
Micke/Micke/Micke
Micke/Micke/Micke/Micke

Men resultatet blir lite konstigt, typ:

Micke
Micke/Micke/Micke/Micke/Micke
Micke/Micke/Micke/Micke/Micke/Micke/Micke

Har fastnat lite och förstår inte hur jag ska få till det, förslag tages tacksamt emot! :)

Medlem sedan feb. 20034 441 inlägg
#2

Kom på vad jag gjorde fel, nu fungerar allt:

function CreateFolders($Data = array(), $Path = ROOTPATH){
	foreach($Data as $Key => $User){
		$Path .= $User['Slug'] . "_" . $User['Id'] . "/";
		@mkdir($Path);
		echo $Path . "<br />";
		if(sizeof($User['Children']) != 0){
			CreateFolders($User['Children'], $Path);
		}
		$Path = str_replace($User['Slug'] . "_" . $User['Id'] . "/", "", $Path);
	}
}

Raden $Path = str_replace($User['Slug'] . "_" . $User['Id'] . "/", "", $Path); efter if-satsen gjorde susen.

Medlem sedan aug. 20039 340 inlägg
#3

Först det första körs $Path .= $User['Slug'] . "/"; två gånger, en gång utanför och en gång i if-satsen. Plocka bort körningen i if-satsen.

För det andra så plussas saker på i varje iteration, när det finns mer än en förgrening. Du vill nog egentligen göra något sådant här:

function CreateFolders($Data = array(), $LocalPath = ROOTPATH){
    foreach($Data as $Key => $User){
        $Path = $LocalPath . $User['Name'] . "/";
...

För det tredje har dina exempeldata ett strukturfel:

                                    [1] => Array
                                        (
                                            [Name] => Micke
                                            [Children] => Array
							(
								[Name] => Micke
								[Children] => Array()
							)
                                        )

Children sak vara en array, och nästa barn ska alltså ligga under [Children] => [0] inte direkt under [Children].

Medlem sedan aug. 20039 340 inlägg
#4

Jag rekommenderar min metod över str_replace-metoden. str_replace-metoden käns som en fullösning.

Medlem sedan feb. 20034 441 inlägg
#5

Aha, strukturfelet i arrayen var mitt fel, ersätte alla värden med "Micke" i mitt exempel och då blev det fel. Jag är inte helt med på vad du menar med att skippa "str_replace". Det fungerar ju att sätta ROOTPATH sålänge man befinner sig på "nivå 1", men om man är på t.ex. nivå 4 och sen ska fortsätta till nivå 3 blir det väl fel?

Medlem sedan aug. 20039 340 inlägg
#6

Hmm? ROOTPATH är ju defaultvärdet och används när du inte skickar med en andra parameter. Den biten fungerar precis likadant som innan.

Notera att det enda jag har gjort med första raden är att byta namn på parametern från $Path till $LocalPath. Detta för att spara undan vilket värde som skickades till funktioen. Sedan en rad som i varje iteration av loopen skapar ett nytt värde för $Path.

Vad du gör istället för att spara undan det medskickade värdet är att först plussa på undermappen i varje iteration och sedan plocka bort undermappen från den påplussade strängen. Fult.

För att sätta mitt förslag i sitt sammanhang:

function CreateFolders($Data = array(), $LocalPath = ROOTPATH){ 
    foreach($Data as $Key => $User){ 
        // Det nya värdet av $Path är inte längre beroende av det gamla värdet av $Path
        $Path = $LocalPath . $User['Slug'] . "_" . $User['Id'] . "/"; 
        @mkdir($Path); 
        echo $Path . "<br />"; 
        if(sizeof($User['Children']) != 0){ 
            CreateFolders($User['Children'], $Path); 
        } 
    } 
}

Ser du nu vad jag är ute efter? :)

Medlem sedan feb. 20034 441 inlägg
#7

Ahh nu är jag med. Tack!

:)

263 ms totalt · 4 externa anrop · v20260731065814-full.6fe65c25
124 ms — deklarationer (db)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)
122 ms — ändringar (db)