webForumDet fria alternativet

Skapa mappar rekursivt från array

6 svar · 861 visningar · startad av MickeA.com

MickeA.comMedlem sedan feb. 20034 441 inlägg
#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! :)

MickeA.comMedlem 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.

nitro2k01Medlem sedan aug. 20039 342 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].

nitro2k01Medlem sedan aug. 20039 342 inlägg
#4

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

MickeA.comMedlem 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?

nitro2k01Medlem sedan aug. 20039 342 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? :)

MickeA.comMedlem sedan feb. 20034 441 inlägg
#7

Ahh nu är jag med. Tack!

:)

132 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
129 ms — hämta tråd, inlägg och bilagor (db)