[PHP] Loopen door array tot aan de top

Pagina: 1
Acties:

Onderwerpen


Verwijderd

Topicstarter
Ik heb de volgende array:
PHP:
1
2
3
4
5
6
7
8
9
10
$menu['producten']
$menu['producten/groenten']
$menu['producten/groenten/winter']
$menu['producten/groenten/winter/groen']
$menu['producten/groenten/winter/groen/spruiten']

$menu['diensten']
$menu['diensten/wekelijks']
$menu['diensten/wekelijks/prepaid']
$menu['diensten/wekelijks/prepaid/strijken']

Ik probeer een functie te schrijven, die de URL pakt en door deze array loopt, totdat de hoofdparent gevonden is. Met andere woorden:
code:
1
2
3
4
5
6
7
8
9
10
11
+------------------------------------------+-----------+
| URL (input)                              | output    |
+------------------------------------------+-----------+
| producten/groenten/winter/groen/spruiten | producten |
+------------------------------------------+-----------+
| producten/groenten/niet/in/array         | producten |
+------------------------------------------+-----------+
| diensten/wekelijks/prepaid               | diensten  |
+------------------------------------------+-----------+
| diensten/wekelijks/3324jkh34jkh4j3h54    | diensten  |
+------------------------------------------+-----------+


Ik heb nu een functie die de URL (hier: $path genaamd) pakt en terugbladert tot het eerste pad dat overeenkomt met een pad in $menu:

PHP:
1
2
3
4
5
6
7
8
9
function menu_get_parent($path) {
  global $menu;

  while ($path && !$menu[$path]) {
    $path = substr($path, 0, strrpos($path, '/'));
  }  

  return $path;
}


Met andere woorden:
code:
1
2
3
4
5
6
7
+------------------------------------------+---------------------+
| URL (input)                              | output              |
+------------------------------------------+---------------------+
| producten/groenten/niet/in/array         | producten/groenten  |
+------------------------------------------+---------------------+
| diensten/wekelijks/3324jkh34jkh4j3h54    | diensten/wekelijks  |
+------------------------------------------+---------------------+


Maar hoe laat ik hem nu verder terugbladeren totdat de top-parent gevonden is?

Verwijderd

string splitten op "/" en dan de eerste uit de resultatenarray pakken?

edit: met explode() dus

[ Voor 30% gewijzigd door Verwijderd op 22-02-2007 16:48 ]


  • Gonadan
  • Registratie: Februari 2004
  • Laatst online: 07:45

Gonadan

Admin Beeld & Geluid, Harde Waren
PHP:
1
2
$array = explode('/', $string);
$top = $array[0]
:)

Look for the signal in your life, not the noise.

Canon R6 | 50 f/1.8 STM | 430EX II
Sigma 85 f/1.4 Art | 100-400 Contemporary
Zeiss Distagon 21 f/2.8


Verwijderd

Topicstarter
Pfff....dank jullie wel! Typisch een gevalletje van "waarom makkelijk doen als het moeilijk kan". Hier stoeide ik nu al een uur mee :o

Verwijderd

kan je nog even toelichten hoe dit uberhaubt in een array terecht komt ;)

ben namelijk wel benieuwd... ik neem aan dat het binnenkomt als $_POST ofzo...

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Exploden lijkt me een vrij overbodige actie hier. :) Ik zou het zelf eerder als volgt aanpakken:
PHP:
1
2
3
4
5
6
$pos = strpos($string, '/');
if ($pos === false) {
  $parent = $string;
} else {
  $parent = substr($string, 0, $pos + 1);
}

Niet dat het verschil performancetechnisch zo groot is, maar ik vind het zelf logischer. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • robbert
  • Registratie: April 2002
  • Laatst online: 20:37
-NMe- schreef op donderdag 22 februari 2007 @ 17:45:
Exploden lijkt me een vrij overbodige actie hier. :) Ik zou het zelf eerder als volgt aanpakken:
PHP:
1
2
3
4
5
6
$pos = strpos($string, '/');
if ($pos === false) {
  $parent = $string;
} else {
  $parent = substr($string, 0, $pos + 1);
}

Niet dat het verschil performancetechnisch zo groot is, maar ik vind het zelf logischer. :)
Volgens mij is die +1 niet nodig, de ts wil de slash er toch niet bij hebben.

Alles in 1 regel gepropt krijg je het volgende: ;)
PHP:
1
$parent = ($pos = strpos($string, '/')) ? substr($string, 0, $pos) : $string;

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

robbert schreef op donderdag 22 februari 2007 @ 18:15:
[...]

Volgens mij is die +1 niet nodig, de ts wil de slash er toch niet bij hebben.
Klopt, foutje. :)
Alles in 1 regel gepropt krijg je het volgende: ;)
PHP:
1
$parent = ($pos = strpos($string, '/')) ? substr($string, 0, $pos) : $string;
Dat wordt om te beginnen redelijk onleesbaar en werkt verder niet wanneer er een slash op positie 0 staat. Dat lijkt me in dit geval niet echt iets dat voor zal komen, maar een beetje defensief programmeren kan nooit kwaad. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Verwijderd

Topicstarter
Een soortgelijk probleem. Ik heb de volgende array en string:
PHP:
1
2
$trail = array('producten/groenten', 'producten', 'nog/iets/geks');
$path = 'producten/groenten/1234/meer';

Ik wil telkens een deel van $path afhalen, totdat ik een match heb in $trail. Als ik een match heb, hoef ik niet verder te zoeken, en retourneer true. Als er helemaal geen match gevonden wordt, retourneer dan false.

In het voorbeeld zal de functie dus eerst kijken of 'producten/groenten/1234/meer' een match in $trail heeft, daarna hetzelfde bij 'producten/groenten/1234' en daarna bij 'producten/groenten'. Hier wordt de match gevonden en er wordt true geretourneerd.
PHP:
1
2
3
4
5
6
7
8
9
function in_trail($path) {
  global $trail;

  while ($path && !in_array($path, $trail)) {
    $path = substr($path, 0, strrpos($path, '/'));
  }

  return $path ? true : false;
}

Maar deze functie retourneert altijd true! Wie snapt waarom?

[ Voor 5% gewijzigd door Verwijderd op 22-02-2007 22:59 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Na een hoop gepruts kwam ik uit op de volgende functie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
function in_trail($trail, $path) {
  while (true) {
  if (in_array($path, $trail)) {
    return true;
  }
  $length = strrpos($path, '/');
  if ($length === false) {
    return false;
  }
  $path = substr($path, 0, $length);
  }
}

Deze werkt goed, maar nu blijkt dat ik een denkfout gemaakt heb. De functie die ik nodig heb, moet meer doen dan telkens maar hakken en vergelijken. De functie omschijving is als volgt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$trail = array('products/veggies/winter', 'products/veggies', 'products');

$path_1 = 'products';                        // true
$path_2 = 'products/423';                    // false
$path_3 = 'products/veggies';                // true
$path_4 = 'products/meat';                   // false
$path_5 = 'products/veggies/23';             // false
$path_6 = 'products/veggies/winter';         // true
$path_7 = 'products/veggies/winter/23/edit'; // true
$path_8 = 'products/meat/cow/dried/54/edit'; // false

// bijvoorbeeld in_trail($trail, $path_1) levert true
  • Het langste element is 'products/veggies/winter'. Ik noem dat in het vervolg "A".
  • De functie vergelijkt $path met $trail. Als er een directe match is, retourneer true.
    • $path_1 en $path_3 en $path_6 hebben een directe match. $path_2, $path_4 en $path_5 retourneren false
  • Als er geen directe match is, EN $path heeft meer elementen dan A, hak dan telkens een deel (na "/") van $path af en kijk of er een match uit rolt met A.

    $path_7 en $path_8 hebben respectievelijk 5 en 6 elementen. Dat is meer dan A heeft, want die heeft er maar 3:
    • We hakken "edit" van $path_7 af. 'products/veggies/winter/23" blijft over. Nog steeds geen match, dus "23" eraf. Blijft over 'products/veggies/winter'. Nu hebben we een match met A, dus return true
    • We hakken "edit" van $path_8 af. 'products/meat/cow/dried/54' blijft over. Geen match dus "54" eraf. 'products/meat/cow/dried" geeft ook geen match, dus "dried" eraf: 'products/meat/cow'. Geen match. De functie kan nu stoppen, want er kan nooit meer een match met A plaatsvinden. Retourneer false
Ik heb problemen om deze werking in een logische volgorde (loop) in een functie te zetten. Datzelfde probleem had ik bij de functie hierboven. Kan iemand mij daar mee op weg helpen?
Pagina: 1