Kategorien
Webdesign

Verzeichnis-Browsing mit PHP

Wer Dateien auf seinem Server zum Download freigibt, nutzt oft die Möglichkeit des Verzeichnis-Browsings. Damit wird dem Benutzer ermöglicht, sich frei in den Verzeichnissen des Servers zu bewegen. Mit etwas PHP kann das Verzeichnis-Browsing beliebig angepasst werden.

Es wird eine PHP-Datei »liste.php« angelegt, in der zunächst ein HTML-Dokument angelegt und eine Tabelle eröffnet werden:

 <html>

    <head>
    <title>Inhalt des Verzeichnisses</title>
    </head>

    <body>

    <table>

Es folgt der PHP-Teil, in dem zunächst einige Variablen angelegt werden:

      <?

    $stamm = "/homepages/x/xxxxxxxxx/htdocs";

    $dir = $stamm.$REQUEST_URI;
    $uri = $REQUEST_URI;

    $verzeichnisse = array();
    $dateien = array();

    $liste = "";

Die Variable $stamm gibt den Serverpfad an, auf den die Domain verweist. $dir gibt den Serverpfad zu dem jeweiligen Verzeichnis an, in dem man sich gerade befindet. $uri verweist auf die aktuelle URI.

Anschließend werden die beiden Arrays $verzeichnisse und $dateien, sowie die Variable $liste angelegt.

Screenshot

Beispielanzeige

Um es zu ermöglichen, beim Browsing in höhere Verzeichnisebenen zu gelangen, wird folgende Anweisung festgelegt:

      if(substr_count($REQUEST_URI, "/") > 1) $liste .= "<tr><td></td><td
    style=\"font-family:monospace\"><a href=\"../\">Eine Ebene h&ouml;her</a></td></tr>\r\n";

Da beim Einlesen des Verzeichnisinhalts Verzeichnisse und Dateien ungeordnet aufgenommen werden, berücksichtigt das Script zunächst nur die Verzeichnisse, um diese später vor den Dateien anzuordnen:

      $lese_dir = opendir($dir);
    while($datei = readdir($lese_dir)) {
      if($datei != ".." && $datei != "." && is_dir($dir.$datei))
    array_push($verzeichnisse, $datei);
    }
    closedir($lese_dir);

Der Variablen $lese_dir wird das aktuelle Verzeichnis mittels opendir() zugewiesen. In der while-Schleife werden mittels readdir() die Dateien des Verzeichnisses einzeln bearbeitet. In der if-Schleife werden mittels is_dir() nur die Verzeichnisse berücksichtigt – mit Ausnahme der beiden Pseudo-Verzeichnisse »..« und ».«.

Die berücksichtigten Verzeichnisse werden in dem Array $verzeichnisse gespeichert.

Die Prozedur wird erneut ausgeführt, um alle Dateien in dem Array $dateien zu speichern:

      $lese_dir = opendir($dir);
    while($datei = readdir($lese_dir)) {
      if(is_file($dir.$datei)) array_push($dateien, $datei);
    }
    closedir($lese_dir);

Anschließend werden die Inhalte der Arrays $verzeichnisse und $dateien alphabetisch geordnet:

      sort($verzeichnisse);
    sort($dateien);

Da Verzeichnisse und Dateien jetzt eingelesen sind, werden sie nacheinander in der Variablen $listte entsprechend aufbereitet gespeichert:

      for($i=0; $i<sizeof($verzeichnisse); $i++) {
      $liste .= "<tr><td></td><td style=\"font-family:monospace\"><a
    href=\"".$uri.$verzeichnisse[$i]."\"
    <".$verzeichnisse[$i]."</a></td></tr>\r\n";
    }

Mittels einer for-Schleife wird jedes Verzeichnis mit einem Link an die Tabelle angegeliedert.

Bei den Dateien wird ähnlich verfahren. Hier werden jedoch auch Dateityp und Dateigröße ausgelesen und ausgegeben:

      for($i=0; $i<sizeof($dateien); $i++) {
      $info = pathinfo($dir.$dateien[$i]);
      $endung = $info["extension"];
      $endung = strtoupper($endung);
      $groesse = filesize($dir.$dateien[$i]);
      if($groesse < 1024) {
        $einheit = "Byte";
      } else if($groesse >= 1024 && $groesse < 1048576)
    {
        $groesse = round($groesse / 1024);
        $einheit = "KB";
      } else {
        $groesse = round($groesse / 1024 / 1024);
        $einheit = "MB";
      }
      $groesse = number_format($groesse, 0, ",", ".");
      $liste .= "<tr><td style=\"font-family:monospace\">".$endung."</td><td
    style=\"font-family:monospace\"><a href=\"".$uri.$dateien[$i]."\">".$dateien[$i]."</a>
    (".$groesse." ".$einheit.")</td></tr>\r\n";
    }

Innerhalb der for-Schleife werden zunächst mittels pathinfo Informationen über die aktuelle Datei eingeholt. In der Variablen $endung wird die Dateiendung der jeweiligen Datei gespeichert. Über strtoupper() wird die Endung in Großbuchstaben dargestellt.

Anschließend wird über filesize() die jeweilige Dateigröße ermittelt und in $groesse gespeichert. Die anschließende if-Anweisung rechnet die Dateigröße gegebenenfalls von Bytes in Kilobytes oder Megabytes um. Über number_format() wird als Tausendertrennzeichen der Punkt gewählt.

Screenshot

Beispielanzeige

Dann wird die Datei mit Angabe der Dateiendung und -größe in $liste gespeichert.

Im letzten Schritt wird der Inhalt von $liste ausgegeben und das HTML-Dokument geschlossen:

      echo $liste;

    ?>

    </table>

    </body>

    </html>

Damit die PHP-Datei »liste.php« in jedem Verzeichnis aufgerufen wird, dürfen in den Verzeichnissen keine Index-Dateien (»index.php«, »index.html« etc.) vorhanden sein. Außerdem muss ein Eintrag in die ».htaccess« gemacht werden:

      ErrorDocument 403 /liste.php

Beide Dateien müssen im Stammverzeichnis zur Domain abgelegt werden. Da beim Nichtvorhandensein einer Index-Datei und ausgeschaltetem Verzeichnis-Browsing in der ».htaccess« ein Fehler 403 erzeugt wird, wird die Datei »liste.php« aufgerufen.

Natürlich lässt sich die Darstellung der Verzeichnisinhalts beliebig abändern. Wer sich die Arbeit machen will, kann zum Beispiel eigene Icons für die verschiedenen Dateitypen entwerfen und statt der bloßen Dateiendung anzeigen lassen. ™

Erstveröffentlichung 08.03.2006

Kategorien
Webdesign

Automatische Sprachauswahl

Vor allem international agierende Unternehmen können auf eine mehrsprachige Internetseite nicht verzichten. Mit ein wenig PHP lässt sich eine Sprachauswahl einfach realisieren.

Zunächst ermitteln wir die Sprache des Benutzers. Diese wird vom Browser bei jedem Seitenaufruf an den Server übermittelt:

 $sprache_vorauswahl = substr($sprache_vorauswahl, 0, 2);

Es wird ein Sprachenkürzel in der Form »de«, »en« etc. an die Variable $sprache_vorauswahl übergeben. Auf diese Weise lässt sich bereits eine Vorauswahl der Sprache treffen. Da einige Browser eine längere Zeichenkette mit weiteren Informationen zur Sprache übermitteln, werden per substr() nur die ersten beiden Zeichen benutzt.

Screenshot

So etwas lässt sich automatisieren

Im nächsten Schritt wird überprüft, ob die Webseite in der ausgewählten Sprache zur Verfügung steht:

    $sprachen = "(de|en)";

    if(preg_match($sprachen, $sprache_vorauswahl) == false) $sprache_vorauswahl
    = "en";

Die Variable $sprachen enthält einen regulären Ausdruck mit den Sprachkürzeln der zur Verfügung stehenden Sprachversionen der Webseite. Über eine Abfrage wird überprüft, ob eine entsprechende Sprachversion vorhanden ist. Falls nicht, wird Englisch als Standardsprache gewählt.

Live Beispiel im neuen Fenster

Im nächsten Schritt werden zwei Variablen gesetzt, die später über die Adresszeile übergeben werden:

      $seite = $_GET["seite"];
    $sprache = $_GET["sprache"];

Über die Variable $seite wechselt man zwischen den einzelnen Unterseiten. $sprache übergibt die aktuell gewählte Sprache.

Falls keine Sprache gewählt ist, wird der Variablen $sprache die Standardsprache zugewiesen:

      if($sprache == "") $sprache = $sprache_vorauswahl;

Falls der Variablen $seite kein Wert zugewiesen wurde, erhält sie automatisch den Wert »index«.

      if($seite == "") $seite = "index";

Damit das Skript funktioniert, müssen Verzeichnis- und Dateinamen speziell benannt werden. Jede Sprachversion steht in einem eigenen Verzeichnis. Der Verzeichnisname entspricht dem Sprachenkürzel. Die Dateien erhalten in diesem Beispiel die Endung ».htt«. Die Datei der Startseite heißt »index.htt«.

Die Verlinkung zu den Unterseiten und den Sprachversionen sollte wie folgt aufgebaut sein:

      <a href="index.php?seite=kontakt&amp;
    sprache=<%sprache%>">Kontakt</a>

Neben der Angabe zur Unterseite muss auch die Sprache übermittelt werden. Über den Platzhalter »<%sprache%>« wird das aktuelle Sprachenkürzel später eingesetzt.

Der Wechsel zwischen den Sprachen sollte so aussehen:

      <a href="index.php?seite=<%seite%>&amp;sprache=en">In
    englisch please!</a>

Hier wird für die Variable $seite ein Platzhalter eingesetzt und für die Sprache ein konkreter Wert.

Über die Variable $ausgabe wird die entsprechende Datei eingelesen:

      $ausgabe = implode("", file($sprache."/".$seite.".htt"));

Das PHP-Skript ersetzt die Platzhalter mit den entsprechenden Variablen:

      $ausgabe = str_replace("<%sprache%>", $sprache, $ausgabe);
    $ausgabe = str_replace("<%seite%>", $seite, $ausgabe);

Zuletzt wird der Inhalt der Variablen $ausgabe ausgegeben:

    echo $ausgabe;

(tm) Erstveröffentlichung 01.06.2005

Kategorien
Webdesign

PHP: E-Mails mit Anhang verschicken

Mit PHP lassen sich bequem E-Mails über das Internet versenden. Selbstverständlich lassen sich auch Dateianhänge mit verschicken. So kann man sich beispielsweise wie bei einem Faxabruf Informationen per E-Mail zukommen lassen.

Zunächst brauchen wir einen HTML-Bereich mit Formular, das zur Eingabe einer E-Mail-Adresse auffordert:

 <html>

    <head>

    <title>PHP: E-Mails verschicken mit Anhang</title>

    </head>

    <body>

    <form action="<? $_SERVER["PHP_SELF"] ?>" method="post">

    <p><input type="text" name="empfaenger" /></p>

    <p><input type="submit" value="E-Mail mit Anhang versenden"
    /></p>

    </form>

    </body>

    </html>

Im vorangestellten PHP-Bereich werden zunächst einige Variablen definiert:

      <?

    $empfaenger = $_POST["empfaenger"];
    $absender = "info@drweb.de";
    $betreff = "E-Mail mit Anhang";
    $text = "Dies ist eine E-Mail mit Anhang.";

In den Variablen werden Empfänger- und Absender-E-Mail-Adresse festgelegt, Betreff der E-Mail und Text. In diesem Beispiel wird nur die Empfänger-E-Mail-Adresse über das Formular eingegeben.

Anschließend geht es um den Dateianhang:

      $datei = "bild.jpg";
    $typ = "image/jpeg";

    $anhang = fread(fopen($datei, "r"), filesize($datei));
    $anhang = chunk_split(base64_encode($anhang));

Die Variable $datei enthält den Namen der Datei, die der E-Mail angehangen werden soll, $typ den MIME-Typ der Datei.

Über die Variable $anhang werden die Binärdaten der Datei mittels fread() eingelesen. Da Dateianhänge in einem speziellen Format vorliegen müssen, wird mittels base64_encode() die Datei entsprechend kodiert. chunk_split() sorgt dafür, dass die kodierte Zeichenkette auf mehrere Zeilen mit je 76 Zeichen verteilt wird.

Die einzelnen Bereiche der E-Mail (E-Mail-Text und die Anhänge) werden durch einen so genannten »Boundary« voneinander getrennt. Der »Boundary« ist eine zufällig generierte Zeichenkette:

      $boundary = md5(uniqid(time()));

Mittels uniqid() wird auf Basis der aktuellen Zeit eine ID erzeugt, aus der mittels md5() eine 32 Zeichen lange Hexadezimalzahl generiert wird.

Jetzt wird der E-Mail-Kopf definiert. Darin befindet sich unter Anderem auch der Anhang. Wichtig sind die Zeilenumbrüche mittels »\n«:

      $kopf = "MIME-Version: 1.0\n";
    $kopf .= "From: ".$absender."\n";
    $kopf .= "Content-Type: multipart/mixed; boundary=".$boundary."\n\n";
    $kopf .= "This is a multi-part message in MIME format -- Dies ist eine
    mehrteilige Nachricht im MIME-Format.\n";

Standardmäßig sollte die MIME-Version und der Absender angegeben werden. In der dritten Zeile des Kopfes wird die Art der E-Mail definiert. Die Angabe »multipart/mixed« gibt an, dass es sich um eine E-Mail mit Anhang handelt. Hier wird auch der »Boundary« definiert.

Anschließend wird ein Hinweistext herausgegeben, der nur angezeigt wird, wenn ein E-Mail-Client mit Multipart-E-Mails nichts anzufangen weiß. Aber das dürfte heutzutage kaum noch zu erwarten sein.

Im nächsten Abschnitt des Kopfes wird der eigentliche E-Mail-Text definiert. Eingeleitet wird dieser Bereich wie auch der folgende über den »Boundary«:

      $kopf .= "--".$boundary."\n";
    $kopf .= "Content-Type: text/plain\n";
    $kopf .= "Content-Transfer-Encoding: 8bit\n\n";
    $kopf .= $text."\n";

Der letzte Abschnitt des Kopfes enthält den Dateianhang:

      $kopf .= "--".$boundary."\n";
    $kopf .= "Content-Type: ".$typ."; name=\"".$datei."\"\n";
    $kopf .= "Content-Transfer-Encoding: base64\n";
    $kopf .= "Content-Disposition: attachment; filename=\"".$datei."\"\n\n";
    $kopf .= $anhang."\n";

Zuletzt wird der E-Mail-Kopf beendet und die E-Mail versendet:

      $kopf .= "--".$boundary."--\n";

    if($empfaenger != "") mail($empfaenger, $betreff, $text, $kopf);

    ?>

Bei Angabe einer E-Mail-Adresse wird über mail() die E-Mail mit den definierten Variablen versandt.

Erstveröffentlichung 12.05.2005

Kategorien
Design HTML/CSS

Die Mischung macht’s: CSS, JavaScript und PHP verstecken Zusatzinformationen

CSS und JavaScript ist es zu danken, dass sich Texte und Bilder ändern lassen, ohne eine Seite neu laden zu müssen. So können beispielsweise Hilfetexte und Zusatzinfos versteckt werden, die dann über einen Link sichtbar gemacht werden. Benutzer ohne JavaScript sind jedoch ausgeschlossen. Doch auch ihnen kann geholfen werden.

Neben der CSS/JavaScript-Variante lässt sich mit ein wenig PHP eine zusätzliche Möglichkeit einbauen, um versteckte Elemente per Link sichtbar zu machen – und das ohne großen Mehraufwand.

Live Beispiel im neuen Fenster

Zunächst einmal die übliche Variante, wie man sie mittels CSS und JavaScript realisiert. Dabei wird zunächst eine JavaScript-Funktion erstellt:

 function sichtbarkeit(id) {
      if(document.getElementById(id).style.display == "none")
    {
        document.getElementById(id).style.display = "inline"
      } else {
        document.getElementById(id).style.display = "none"
      }
    }

Der HTML-Bereich sieht so aus:

      <p>Hier steht ein Text, der einige Informationen enth&uml;lt.</p>

    <p><a href="#" onclick="sichtbarkeit('text1'); return
    false">Mehr Infos</a>

    <span id="text1" style="display:hidden"><br />Hier
    steht der zus&auml;tzliche Informationstext, der eigentlich unsichtbar
    ist.</span></p>

    <p>Hier steht noch ein Text.</p>

Der »versteckte« Bereich steht innerhalb einer span-Auszeichnung und erhält in diesem Fall die ID text1. Über CSS wird der Bereich mittels display:hidden versteckt.

Über einen Link wird die Funktion sichtbarkeit() aufgerufen und die ID des unsichtbaren Bereichs übergeben. Die Funktion prüft, ob die CSS-Eigenschaft auf none oder inline gesetzt ist und verändert sie.

Auf diese Weise lassen sich Informationen ohne erneutes Laden der Seite sichtbar und wieder unsichtbar machen. Wer jedoch JavaScript deaktiviert hat, muss schon in den Quelltext schauen, um den versteckten Text zu sehen.

Abhilfe kann da etwas PHP schaffen. Dazu wird ein kleiner PHP-Bereich vor dem HTML-Bereich definiert:

      <?

    $id = $_GET["id"];
    $display = $_GET["display"];

    $display_ist_text1 = "none";
    $display_soll_text1 = "inline";

    if($id == "text1" && $display == "inline") {
      $display_ist_text1 = "inline";
      $display_soll_text1 = "none";
    } else if($display == "none") {
      $display_ist_text1 = "none";
      $display_soll_text1 = "inline";
    }

    ?>

Zunächst werden im PHP-Bereich die beiden Variablen $id und $display definiert. Die Werte werden über einen Link übergeben.

Außerdem werden für jeden unsichtbaren Bereich jeweils zwei Variablen definiert. In diesem Fall sind das $display_ist_text1 und $display_soll_text1. Sie erhalten als Wert die beiden möglichen Eigenschaften der CSS-Eigenschaft display. Die Variablen werden später im HTML-Bereich eingesetzt.

Darüber hinaus wird für jeden unsichtbaren Bereich eine if-Abfrage definiert. Sie ermittelt für die entsprechende ID die neuen Werte für $display_ist_text1 und $display_soll_text1.

Der HTML-Bereich muss für die PHP-Funktionlität verändert werden:

      <p>Hier steht ein Text, der einige Informationen enth&uml;lt.</p>

    <p><a href="<? echo $_SERVER["PHP_SELF"] ?>?id=text1&display=<?
    echo $display_soll_text1 ?>" onclick="sichtbarkeit('text1');
    return false">Mehr Infos</a>

    <span id="text1" style="display:<? echo $display_ist_text1
    ?>"><br />Hier steht der zus&uml;tzliche Informationstext,
    der eigentlich unsichtbar ist.</span></p>

    <p>Hier steht noch ein Text.</p>

Der Link zum Darstellen des versteckten Bereichs erhält neben dem JavaScript-Aufruf auch noch einen gewöhnlichen Verweis. Dabei wird die Datei einfach erneut geladen und die Variablen id und display werden übergeben. Die Variable display erhält den Wert der PHP-Variablen $display_soll_text1.

Die CSS-Eigenschaft display wird über die PHP-Variable $display_ist_text1 gesetzt.

Über die if-Abfrage im PHP-Bereich wird der Wert für display geändert.

Im JavaScript-Aufruf verhindert return false, dass der voran stehende Verweis nicht ausgeführt wird. Nur bei deaktiviertem JavaScript wird der Verweis ausgeführt.

Erstveröffentlichung 28.04.2005