Sven Rautenberg: Und schon sind sie da, die ersten Problemchen... :-)

Beitrag lesen

Moin!

Ich hab mal was zusammengebastelt:

Etwas, was ziemlich kompliziert ist, und wesentlich einfacher sein könnte. War ja zu erwarten, das. :)

Wie ich deinem Code entnehme, bastelst du an Vorarbeiten zur Realisierung einer automatischen Brotkrumennavigation.

Die Eckdaten:
Eingangsdatum ist als einziges ein Pfad zur aktuell darzustellenden Datei. Ausgangsdaten sollen Links zu allen übergeordneten Dateien sein, wobei dazu die Index-Seite (URL endet auf Slash) des die aktuelle Seite enthaltenden Verzeichnisses sowie aller übergeordneter Verzeichnisse sein soll. Dass diese Links funktionieren, dafür ist der Webmaster durch Anlegen entsprechender Seiten selbst verantwortlich (eine Prüfung dafür zu integrieren, wäre aber natürlich möglich).

Als Schema:
Der URL- bzw. Dateipfad "includes/javascript/popups/irgendwas.txt" soll zerlegt werden:
Linktext:     Ziel:
irgendwas     "includes/javascript/popups/irgendwas.txt"
popups        "includes/javascript/popups/"
javascript    "includes/javascript/"
includes      "includes/"

(Ja, die letzte Stufe ist nicht so wirklich Ideal - aber es geht ums Prinzip, nicht um eine fertig nutzbare Lösung.)

Und wenn ich jetzt mal deinen Code kommentiere...

<?php
Error_Reporting(E_ALL);
$link = "Startseite";
$title = "Das ist ein Seitentitel";                     //wird später aus Array ausgelesen.c
$string ="includes/javascript/popups/irgendwas.txt";                     //wird später aus Array ausgelesen.

$intermediate = explode("/",$string);

Bis hierhin ist alles toll - vielleicht mit Ausnahme des Variablennamens $intermediate - der wäre mir persönlich viel zu lang und zu wenig beschreibend.

$count = 0;
foreach($intermediate as $elem)
 {
  $count++;
 }

Oh, Wahnsinn. Du willst ermitteln, wieviele Elemente sich im Array $intermediate befinden. Wozu gibts eigentlich die Funktion count()? ... :)

switch($count)
 {
  case 2:
  $temp = $intermediate[0];
  $file = $intermediate[1];
  break;
 case 3:
  $temp = $intermediate[0];
  $path = $intermediate[1];
  $file = $intermediate[2];
  break;
 case 4:
  $temp = $intermediate[0];
  $path = $intermediate[1];
  $subpath = $intermediate[2];
  $file = $intermediate[3];
  break;
 }

Bei Switch ist kein Fall für Werte kleiner als 2 vorgesehen. Und kein Fall für Werte größer als 4.

Warum die einzelnen Werte hier umkopiert werden, ist auch nicht ersichtlich. Die Werte aus $intermediate werden 1:1 in neue Variablen gepackt - schön nach Fällen getrennt.

$link = strtoupper($link);

Hm, das hier könnte man auch weiter oben schon erledigen - also direkt oben bei $link = "STARTSEITE" anstatt $link="Startseite". Aber du willst ja universelleren Code, und $link wird nicht unbedingt so simpel definiert werden.

Aber das hier:

if ($count>=3)
 {
  $path = strtoupper($path);
 }
if ($count==4)
 {
  $subpath = strtoupper($subpath);
 }

Warum unterscheidest du hier nochmal zwei Fälle, obwohl du im vorhergehensen switch() doch auch einfach hättest schreiben können:

case 3:
$path = strtoupper($intermediate[1]);
break;
case 4:
$path = strtoupper($intermediate[1]);
$subpath = strtoupper($intermediate[2]);
break;

$temp = str_replace($temp,' <a href="index.php">'.$link.'</a> ',$temp);

Diese Zeile erscheint mir auch etwas stark überfrachtet mit Funktionalität. Gemäß deiner Zeilen weiter oben steht in $temp immer das erste Verzeichnis "includes" drin.

Deine Anwendung der str_replace-Funktion sorgt nun dafür, dass in der Variablen $temp das Vorkommen des Textes, welcher sich in der Variablen $temp befindet, durch den Text ' <a href="index.php">'.$link.'</a> ' ersetzt wird.

Diese Ersetzung gilt immer. Da egal, was in $temp drinsteht, der gesamte Text immer durch den neuen ersetzt wird, kannst du genausogut auch einfach schreiben:

$temp = ' <a href="index.php">'.$link.'</a> ';

Und fertig.

$file = str_replace($file,$title,$file);

Hier genau dasselbe. Du tauscht in der Variablen $file den Komplettinhalt der Variablen $file gegen den Inhalt der Variablen $title.

Einfacher: $file = $title;

Noch einfacher: Es weglassen, und einfach $title verwenden.

switch($count)
 {
  case 2:

Und hier verzweigst du wieder je nach Anzahl der gefundenen Bestandteile, wie schon zuvor oben.

Das könnte man insgesamt auch stark vereinfachen, indem man wirklich nur einmal verzweigt, und jeweils alle notwendigen Aktivitäten zur Ausgabe einer Brotkrumennavigation für die jeweilige Stufe ausgibt.

echo $temp." » ".$file;
  break;
  case 3:
  echo $temp." » ".$path." » ".$file;
  break;
  case 4:
  echo $temp." » ".$path." » ".$subpath." » ".$file;
  break;
 }
unset($count);
unset($intermediate);

Hinterher die Variablen löschen, um Spuren zu verwischen? Naja, unnötig, aber nicht unbedingt falsch.

?>

Mir scheint die Lösung mit $count nicht so ganz der Bringer zu sein, ich weiss aber nicht, wie ich das anders lösen könnte.
Wäre nett, wenn mir da jemand den einen oder anderen Denkanstoß liefern könnte.

Grundlage effiziennten Programmierens ist es, Gleichheiten zu erkennen, sinnvoll zusammenzufassen und in einen mehr oder weniger universellen Code zu packen.

Soll heißen: Deine Aufgabe besteht eigentlich nur darin, deinen Pfad in Einzelteile zu zerhacken, und jeden einzelnen "irgendwie" passend zu verarbeiten. Dabei ist es für eine Brotkrumennavigation eher irrelevant, ob du nun zwei, drei, vier oder noch mehr Verzeichnisse im Pfad hast - alle müssen ja, da sie die Dokumentenstruktur repräsentieren, irgendwie gleichartig verarbeitet und in Links oder zumindest Text umgesetzt werden.

Mit anderen Worten:
Splitte den Pfad in Einzelelemente.
Das erste Element wird ignoriert. Stattdessen wird ein Standardlink auf die Startseite ausgegeben (echo).

Alle weiteren Elemente (Array-Index 1 bis unendlich) werden wie folgt behandelt:
Wenn das aktuelle Element nicht das letzte ist, dann wird der Text, der im Array beim aktuellen Index steht (meinetwegen auch strtoupper() gemacht) ausgegeben.
Wenn das aktuelle Element das letzte ist, wird der Seitentitel ausgegeben.

In Code umgesetzt:

<?php
Error_Reporting(E_ALL);
$link = "Startseite";
$title = "Das ist ein Seitentitel";                     //wird später aus Array ausgelesen.c
$string ="includes/javascript/popups/irgendwas.txt";

$pfad = explode("/",$string); // ein schön kurzer, bezeichnender Arrayname ;)

echo ' <a href="index.php">'.$link.'</a> ';

for ($i=1; $i<count($pfad); $i++)
{
  if ($i < count($pfad))
  {
    echo " » ".strtoupper($pfad[$i]);
  }
  else
  {
    echo " » ".$title;
  }
}
?>

Und fertig. Sollte (ich habe es nicht 100% geprüft - und insbesondere den Code nicht getestet) so ungefähr dasselbe ausgeben, wie dein Code auch - nur eben wesentlich kürzer und übersichtlicher.

Und (großes Plus): Da eine Brotkrumennavigation wenig Sinn macht, wenn man die einzelnen Links nicht auch anklicken kann: Hier hast du jetzt eine einzige Zeile, die für die Ausgabe der (jetzt noch nicht) Links zuständig ist (direkt nach dem IF). Dort kannst du deinen Link zusammenbasteln.

Beispiel: Wenn du einen Link der Form href="/includes/pfad/subpfad/" je nach Bedarf zusammensetzen willst, dann böte sich dafür folgendes an:

echo " $raquo; <a href="/".implode("/",array_slice($pfad,0,$i+1))."/">".strtoupper($pfad[$i])."</a>";

Ja, das ist ein starker Tobak - PHP hat so viele wunderbare Funktionen, die einem viel Arbeit abnehmen.

array_slice gibt einen Teil eines Arrays als Array zurück. Die drei Parameter sind: 1. Das große Array, 2. Das Startelement, 3. Die Anzahl der Elemente.

Und dieses Teilarray wird mit implode() wieder zu einem String zusammengebacken.

Schau dir im Zweifel einfach mal die Beispiele bei php.net an, um zu verstehen, was da bei array_slice passiert. http://de2.php.net/manual/de/function.array-slice.php

Und wenn jetzt noch Klarheiten bestehen: Die kriege ich auch noch weg. :)

- Sven Rautenberg

--
Die SelfHTML-Developer sagen Dankeschön für aktuell 20885,68 Euro Spendengelder!