Ximena: neue Datei erstellen

Hallo ihr Lieben :)

Ich versuche mich gerade selbst etwas in PHP einzuführen. Ich mache das aus reinem Spass, weil es mich interessiert.

Momentan möchte ich eine Seite erstellen, auf der man sich registrieren kann. Dabei wird der Benutzername und das Passwort in einer Datenbank gespeichert. Was nun aber dazu kommen soll ist, dass ich eine neue Datei erstellen möchte, die den Namen des neu registrierten Benutzers trägt. Diese Datei soll in denselben Ordner gespeichert werden, in dem alle Dateien der Homepage sind.

Die Seite läuft momentan nur auf meinem XAMPP Server und noch nicht im Internet.

Meine Seite 'registration.php' hat folgenden Inhalt:

<head>  
    <meta http-equiv="content-type" content="text/html; charset=utf-8">  
    <link rel="stylesheet" type="text/css" href="HomepageStyle.css">  
</head>  
  
<div id="text">  
<?php  
$verbindung = mysql_connect("localhost", "*-*" , "*-*")  
or die("Verbindung zur Datenbank konnte nicht hergestellt werden");  
  
mysql_select_db("*-*") or die ("Datenbank konnte nicht ausgewählt werden");  
  
$username = $_POST["username"];  
$passwort = $_POST["passwort"];  
$passwort2 = $_POST["passwort2"];  
  
if($passwort != $passwort2 OR $username == "" OR $passwort == "")  
    {  
    echo "<div id=\"titel\">Sie haben nicht alle Felder korrekt ausgefüllt.</div>  
    <br><br>  
    Eingabefehler. Bitte alle Felder korrekt ausfüllen.  
    <a href=\"registrieren.php\">Zurück</a>";  
    exit;  
    }  
$passwort = md5($passwort);  
  
$result = mysql_query("SELECT id FROM login WHERE username LIKE '$username'");  
$menge = mysql_num_rows($result);  
  
if($menge == 0)  
    {  
    $eintrag = "INSERT INTO login (username, passwort) VALUES  
    ('$username', '$passwort')";  
    $eintragen = mysql_query($eintrag);  
  
    if($eintragen == true)  
        {  
        $dateiname = "$username _geheim.php"; //HIER  
        fOpen($dateiname , "a+"); //HIER  
        echo "<div id=\"titel\">Ihr Benutzername wurde erfolgreich angelegt.</div>  
        <br><br>  
        Benutzername <b>$username</b> wurde erstellt.  
        <a href=\"anmelden.php\">Anmelden</a>";  
        }  
    else  
        {  
        echo "<div id=\"titel\">Ihr Benutzername konnte nicht angelegt werden.</div>  
        <br><br>  
        Fehler beim Speichern des Benutzernames.  
        <a href=\"registrieren.php\">Zurück</a>";  
        }  
    }  
else  
    {  
    echo "<div id=\"titel\">Ihren Benutzernamen gibt es schon.</div>  
    <br><br>  
    Benutzername schon vorhanden. <a href=\"registrieren.php\">Zurück</a>";  
    }  
?>  
</div>

Dort wo die beiden HIER stehen, sollte nun der Code für das Erstellen des Ordners stehen. Aber irgendwie bekomme ich immer eine Fehlermeldung.
Kann mir jemand helfen?

Liebe Grüsse
Ximena

  1. Hallo Ximena,

    Was nun aber dazu kommen soll ist, dass ich eine neue Datei erstellen möchte, die den Namen des neu registrierten Benutzers trägt. Diese Datei soll in denselben Ordner gespeichert werden, in dem alle Dateien der Homepage sind.

    $dateiname = "$username _geheim.php"; //HIER
            fOpen($dateiname , "a+"); //HIER

    Dort wo die beiden HIER stehen, sollte nun der Code für das Erstellen des Ordners stehen. Aber irgendwie bekomme ich immer eine Fehlermeldung.
    Kann mir jemand helfen?

    Möchtest du einen Ordner oder eine Datei anlegen?
    Bei dem Zusammensetzen des Dateinamens hast du ein Leerzeichen drin, ist das gewollt? Ansonsten müsstest du den String per Stringverknüpfung zusammensetzen:

    $dateiname = $username."_geheim.php";

    Im zweiten Schritt öffnest du die Datei. An sich wirft das noch keinen Fehler, aber  fopen() möchte gern ein Ergebnis zurückgegeben.

    $result = fOpen($dateiname , "a+");

    Du solltest allerdings zum Schluß die Datei wieder schließen mit fclose.

    ciao
    romy

    1. Tach!

      Bei dem Zusammensetzen des Dateinamens hast du ein Leerzeichen drin, ist das gewollt? Ansonsten müsstest du den String per Stringverknüpfung zusammensetzen:
      $dateiname = $username."_geheim.php";

      Nicht zwingend. Man kann auch mit der {}-Syntax den Variablennamen genauer spezifizieren.

      Im zweiten Schritt öffnest du die Datei. An sich wirft das noch keinen Fehler, aber  fopen() möchte gern ein Ergebnis zurückgegeben.
      $result = fOpen($dateiname , "a+");

      Es ist kein Fehler, ein Funktionsergebnis nicht entgegennehmen. Im Falle von fopen() ist es aber sinnlos, das nicht zu tun, denn das Filehandle braucht man ja noch zu Schreiben. Wenn es nur darum geht, dass die Datei existiert, dann: touch().

      Du solltest allerdings zum Schluß die Datei wieder schließen mit fclose.

      Muss man nicht unbedingt, das macht PHP am Script-Ende sowieso. Notwendig ist es sozusagen nur, wenn das Script noch eine Zeit lang weiterläuft, die Datei dazu aber nicht braucht, und man sie für nebenläufige Scripts freigeben will. Apropos Nebenläufigkeit: Dateisperren helfen, konkurrierende Zugriffe zu ordnen.

      dedlfix.

      1. Hallo dedlfix,

        Nicht zwingend. Man kann auch mit der {}-Syntax den Variablennamen genauer spezifizieren.

        Ja ich weiß ;) Ich wollte es nicht verkomplizieren.

        Es ist kein Fehler, ein Funktionsergebnis nicht entgegennehmen. Im Falle von fopen() ist es aber sinnlos, das nicht zu tun, denn das Filehandle braucht man ja noch zu Schreiben. Wenn es nur darum geht, dass die Datei existiert, dann: touch().

        Verdammt, ich hab mich totgesucht, dabei ist es so einfach. Sowas wollte ich ihr auch raten, aber war wohl vorhin Suchborniert ;)

        Muss man nicht unbedingt, das macht PHP am Script-Ende sowieso. Notwendig ist es sozusagen nur, wenn das Script noch eine Zeit lang weiterläuft, die Datei dazu aber nicht braucht, und man sie für nebenläufige Scripts freigeben will.

        Das ist interessant, wußte ich noch nicht. Finde es aber trotzdem irgendwie sauberer, sie wieder zu schließen, wenn man sie nicht braucht.

        Danke für die Zusatzinfos!

        ciao
        romy

  2. Hallo,

    Ich versuche mich gerade selbst etwas in PHP einzuführen. Ich mache das aus reinem Spass, weil es mich interessiert.

    trotzdem solltest du dir gleich von Anfang an angewöhnen, es richtig[tm] zu machen und dir nicht irgendwelche Schlampereien angewöhnen, die dir später große Sicherheitslöcher aufreißen. Eins ist jetzt schon erkennbar.

    Momentan möchte ich eine Seite erstellen, auf der man sich registrieren kann. Dabei wird der Benutzername und das Passwort in einer Datenbank gespeichert. Was nun aber dazu kommen soll ist, dass ich eine neue Datei erstellen möchte, die den Namen des neu registrierten Benutzers trägt. Diese Datei soll in denselben Ordner gespeichert werden, in dem alle Dateien der Homepage sind.

    Ich verkneife mir jetzt mal die Frage nach dem Sinn. ;-)

    <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <link rel="stylesheet" type="text/css" href="HomepageStyle.css">
    </head>

    <div id="text">

      
    Hmm. Kein DOCTYPE? Kein öffnendes html-Tag? Kein öffnendes body-Tag?  
      
    
    > <?php  
    > $verbindung = mysql\_connect("localhost", "\*-\*" , "\*-\*")  
    > or die("Verbindung zur Datenbank konnte nicht hergestellt werden");  
    >   
    > mysql\_select\_db("\*-\*") or die ("Datenbank konnte nicht ausgewählt werden");  
      
    Mittelfristig solltest du dir eine bessere "Fehlerbehandlung" ausdenken als einen Selbstmord des Scripts. Für den Anfang mag ein die() ausreichen; gut ist es nicht.  
      
    
    > $username = $\_POST["username"];  
    > $passwort = $\_POST["passwort"];  
    > $passwort2 = $\_POST["passwort2"];  
      
    Wozu das Umkopieren?  
      
    
    > $result = mysql\_query("SELECT id FROM login WHERE username LIKE '$username'");  
      
    Da ist sie schon, die Sicherheitslücke. Du übergibst $username, eine exakte Kopie von $\_POST['username'], ungeprüft an die Datenbank. Don't do that! Never! Da es sich um eine Eingabe vom Client handelt, könnte da \_alles\_ drinstehen, und das kann deine Datenbank gehörig durcheinanderbringen.  
      
    
    >     $eintrag = "INSERT INTO login (username, passwort) VALUES  
    >     ('$username', '$passwort')";  
    >     $eintragen = mysql\_query($eintrag);  
      
    Dito.  
      
    
    >     if($eintragen == true)  
      
    "Wenn es wahr ist, dass $eintragen wahr ist, dann ..."  
    Ein einfaches  if ($eintragen)  wäre leichter zu lesen und "logischer". Andererseits stammt der Wert aus dem Aufruf von mysql\_query(), das nicht in jedem Fall ein boolsches Resultat liefert (in diesem Fall schon, wegen des INSERT-Statements). Wenn du also schon Wert darauf legst, wirklich die boolschen Werte true oder false abzuprüfen, solltest du einen typsicheren Vergleich notieren (also mit dem Operator ===).  
      
    
    >         $dateiname = "$username \_geheim.php"; //HIER  
    >         fOpen($dateiname , "a+"); //HIER  
    > [...]  
    > Dort wo die beiden HIER stehen, sollte nun der Code für das Erstellen des Ordners stehen.  
      
    Ordner? Ich dachte, du wolltest eine Datei erstellen. Und willst du nachher wirklich \_automatisch\_ PHP-Code in diese Datei schreiben? Auch das kann gefährlich sein, je nachdem, woher dieser Code später kommt. Falls es kein PHP-Code ist, der da gespeichert werden soll, würde ich auch nicht die Endung ".php" wählen. Immerhin kann später jeder, der den Namen kennt, die Ressource direkt im Browser aufrufen und so den darin enthaltenen Code ausführen.  
      
    
    > Aber irgendwie bekomme ich immer eine Fehlermeldung.  
      
    Dann verrate uns nur ja nicht, welche. Es könnte die Hilfe erleichtern! ;-)  
      
    
    > Kann mir jemand helfen?  
      
    Nicht, wenn du wichtige Informationen verschweigst.  
      
    Ciao,  
     Martin  
    
    -- 
    Das Gehirn ist schon eine tolle Sache: Es fängt ganz von allein an zu arbeiten, wenn man morgens aufsteht, und hört erst damit auf, wenn man in der Schule ankommt.  
      (alte Schülererkenntnis)  
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    
    1. Tach!

      Andererseits stammt der Wert aus dem Aufruf von mysql_query(), das nicht in jedem Fall ein boolsches Resultat liefert (in diesem Fall schon, wegen des INSERT-Statements). Wenn du also schon Wert darauf legst, wirklich die boolschen Werte true oder false abzuprüfen, solltest du einen typsicheren Vergleich notieren (also mit dem Operator ===).

      Ja, aber nicht um jeden Preis und auch nicht aus Prinzip, nur um nicht nachdenken/-lesen zu müssen. Typsicher muss der Vergleich nur dann werden, wenn Verwechslungen auftreten können, also zum Beispiel wenn 0 und false unterschieden werden müssen. mysql_query() liefert hingegen false nur im Fehlerfall, und im Gutfall immer einen eindeutig nicht mit false verwechselbaren Wert. Anders läge der Fall bei PDO::exec(), das die Anzahl der betroffenen Datensätze zurückgibt. Dabei ist 0 und das Fehlerfall-false verwechselbar. Üblicherweise steht im PHP-Handbuch in solchen Fällen eine auffällige Warnung.

      Sinnlose typsichere Vergleiche bremsen (mich) beim Code-Lesen, weil dann die Frage aufkommt, warum hier typsicher vergleichen werden muss, welche zweideutigen Werte erwartet der Autor denn hier?

      if ($variable === 'foo')

      Nur ein String mit dem Inhalt foo ist gleich dem Stringliteral 'foo'. Es gibt keinen anderen Wert eines anderen Typs, der diese Bedingung erfüllen kann. Es wäre hier also eine komplett sinnlose Verwendung eines typsicheren Vergleichs.

      dedlfix.

      1. Tach!

        Sinnlose typsichere Vergleiche bremsen (mich) beim Code-Lesen, weil dann die Frage aufkommt, warum hier typsicher vergleichen werden muss, welche zweideutigen Werte erwartet der Autor denn hier?

        if ($variable === 'foo')

        Nur ein String mit dem Inhalt foo ist gleich dem Stringliteral 'foo'. Es gibt keinen anderen Wert eines anderen Typs, der diese Bedingung erfüllen kann. Es wäre hier also eine komplett sinnlose Verwendung eines typsicheren Vergleichs.

        Oh, hier muss ich mich revidieren. Ein Blick auf die PHP type compaision tables zeigt mir einen Fehler auf. Sowohl true als auch 0 (aber nicht '0' als String) werden im einfachen Vergleich zu einem nichtleeren String als gleich angesehen. Die Typen Integer und Boolean sind hier anscheinend die dominanten Typen und zwingen bei einem Vergleich den String zu einer Typkonvertierung. Ein nicht numerischer String konvertiert nach Integer ergibt 0.

        Das obige Beispiel ist also nur dann sinnlos, wenn $variable aus einer Quelle stammt, die nur Strings liefert, zum Beispiel ein Eintrag in $_POST oder $_GET.

        dedlfix.

  3. Tach!

    $verbindung = mysql_connect("localhost", "*-*" , "*-*")
    or die("Verbindung zur Datenbank konnte nicht hergestellt werden");
    mysql_select_db("*-*") or die ("Datenbank konnte nicht ausgewählt werden");

    Findest du es aus Sicht den Benutzers sinnvoll, wenn er im Falle eines Fehlers ein abgebrochenes Script und solche Fehlermeldungen zu Gesicht bekommt? Der Benutzer hatte ein Ziel. Aufgrund eines technischen Problems kann er dieses nicht erreichen. Was für Alternativen hat er? Sag sie ihm.

    $username = $_POST["username"];
    $passwort = $_POST["passwort"];
    $passwort2 = $_POST["passwort2"];

    Immer wieder zu sehen und doch ist und bleibt es sinnlos, die Werte vor dem Gebrauch noch einmal umzukopieren.

    $result = mysql_query("SELECT id FROM login WHERE username LIKE '$username'");

    Sehr schön. Wenn du solch eine Query zur Abfrage der Benutzerdaten nimmst und ich nun ' OR 1 #  heiße, dann bin ich als der erste Nutzer im System angemeldet, was meist der Admin ist. Beachte die Kontextwechsel, wenn dir deine Daten lieb sind.

    $dateiname = "$username _geheim.php"; //HIER
            fOpen($dateiname , "a+"); //HIER
    Dort wo die beiden HIER stehen, sollte nun der Code für das Erstellen des Ordners stehen. Aber irgendwie bekomme ich immer eine Fehlermeldung.
    Kann mir jemand helfen?

    Ich hätte ja ein paar Lösungsvorschläge auf Lager. Nur nützt es dir nichts, wenn ich dir dazu die Details verschweige. Allgemein kann ich dir nur raten: Beseitige die in der Fehlermeldung genannte Ursache - wie auch immer sie lautet.

    dedlfix.

    1. gudn tach!

      $username = $_POST["username"];
      $passwort = $_POST["passwort"];
      $passwort2 = $_POST["passwort2"];

      Immer wieder zu sehen und doch ist und bleibt es sinnlos, die Werte vor dem Gebrauch noch einmal umzukopieren.

      kann (= muss nicht = kommt darauf an) lesbarkeit des codes beguenstigen.

      prost
      seth

      1. Tach!

        Immer wieder zu sehen und doch ist und bleibt es sinnlos, die Werte vor dem Gebrauch noch einmal umzukopieren.
        kann (= muss nicht = kommt darauf an) lesbarkeit des codes beguenstigen.

        Wann zum Beispiel begünstigen doppelt so viel Variablen wie notwendig die Lesbar- und Verständlichkeit des Codes? Der Kontext POST/GET-Parameter geht bei einem neuen Variablennamen auch verloren, zumal der Wert keine weitere Änderung erfährt.

        dedlfix.

        1. gudn tach!

          Immer wieder zu sehen und doch ist und bleibt es sinnlos, die Werte vor dem Gebrauch noch einmal umzukopieren.
          kann (= muss nicht = kommt darauf an) lesbarkeit des codes beguenstigen.

          Wann [...]?

          bei relativ kleinen funktionen mit vielen zugriffen (vielleicht auch mehrere innerhalb einer zeile) auf diese variablen wird dadurch der code kuerzer und u.u. besser lesbar, wenn der kontext ("variable kommt von $_POST") klar ist.

          es gibt ja auch komplizierteres als
            $username = $_POST["username"];
          naemlich z.b.
            $username = $_POST["foo"]->[$moep]["username"]; # oder aehnliches

          es kann z.b. auch fuer die lesbarkeit sinnvoll sein, komplizierte berechnungen nicht in einer langen zeile auszufuehren, sondern sowas in mehrere einzelschritte aufzuteilen. die performance, die dadurch draufgeht, ist in scriptsprachen meist vernachlaessigbar.

          prost
          seth

          1. Tach!

            Immer wieder zu sehen und doch ist und bleibt es sinnlos, die Werte vor dem Gebrauch noch einmal umzukopieren.
            kann (= muss nicht = kommt darauf an) lesbarkeit des codes beguenstigen.
            Wann [...]?
            bei relativ kleinen funktionen mit vielen zugriffen (vielleicht auch mehrere innerhalb einer zeile) auf diese variablen wird dadurch der code kuerzer und u.u. besser lesbar, wenn der kontext ("variable kommt von $_POST") klar ist.

            Warum übergibst du dann nicht der Funktion diesen Wert als Parameter? Die Funktion selbst wird dadurch universell, weil sie nun völlig ohne eine Bindung an eine bestimmte Datenquelle auskommt.

            es gibt ja auch komplizierteres als
              $username = $_POST["username"];
            naemlich z.b.
              $username = $_POST["foo"]->[$moep]["username"]; # oder aehnliches

            Kaum. Es sei denn, du schreibst selbst Objekte (wegen des ->) in das $_POST-Array. Dann musst du dich aber fragen lassen, warum du das machst. PHP macht das nicht, also darf eigentlich auch kein Programmteil davon ausgehen, so etwas vorzufinden.

            Aber mal angenommen, du hättest nur Array-Zugriffe notiert ... die Daten auf solche eine Weise schachteln zu müssen, verlangt im Prinzip auch einen weit über 08/15 hinausgehenden Anwendungsfall und bedingt durch dessen Code-Größe eine angemessene Strukturierung des Codes. Dann käme wieder die Frage von oben ins Spiel.

            es kann z.b. auch fuer die lesbarkeit sinnvoll sein, komplizierte berechnungen nicht in einer langen zeile auszufuehren, sondern sowas in mehrere einzelschritte aufzuteilen.

            Auch hier wieder die Frage, warum dann nicht die komplizierte Berechnung als eine abgeschlossene Einheit separieren und ordentlich in einer Funktion mit Parameterübergabe kapseln?

            die performance, die dadurch draufgeht, ist in scriptsprachen meist vernachlaessigbar.

            Die spielt auch beim unnötigen Umkopieren keine Rolle. Zum einen sind die Daten üblicherwiese handlich klein und der kopiervorgang fiele nicht ins Gewicht. Aber auch bei sehr großen Daten wird seitens PHP keine Kopie angelegt. Intern wird quasi nur eine Referenz angelegt. Der eigentliche Dupliziervorgang findet erst dann statt, wenn beide Variableninhalte auseinanderlaufen, also einer von beiden geändert wird.

            Unsere Diskussion läuft grad auf der theoretischen Ebene ab. Da sollte man auch annehmen, dass man die theoretisch beste Lösung verwenden und vertreten kann. Dass die Praxis da mitunter eine ganz andere Sprache spricht, ist mir klar. Wenn man wegen ihrer Zwänge nicht mit einer "ordentlichen" Lösung zum Ziel kommt, dann muss man eben Alternativen finden, wie sie normalerweise nicht gelehrt werden würden. Aber für solch einfache Anwendungsfälle wie die der meisten Wald- und Wiesen-Scripte, muss man nicht unbedingt darauf plädieren, dass ein einfaches Umkopieren sinnvoll sei.

            dedlfix.

            1. gudn tach!

              bei relativ kleinen funktionen mit vielen zugriffen (vielleicht auch mehrere innerhalb einer zeile) auf diese variablen wird dadurch der code kuerzer und u.u. besser lesbar, wenn der kontext ("variable kommt von $_POST") klar ist.

              Warum übergibst du dann nicht der Funktion diesen Wert als Parameter? Die Funktion selbst wird dadurch universell, weil sie nun völlig ohne eine Bindung an eine bestimmte Datenquelle auskommt.

              ja, dachte mir beim schreiben, dass du diesen - berechtigten - einwand bringen wirst. grundsaetzlich sollte man das so tun, das stimme ich dir zu. so wie es auch richtig ist, dass umkopieren meist sinnlos ist. meine antwort zielte auf ausnahmefaelle ab, weil mir deine formulierung zu pauschal war.

              wenn eine funktion (ich spreche jetzt mal in perl-terminologie, weil ich die von php nicht so gut kenne) von einer komplizierten hash-reference diverse eintraege benoetigt und davon ausgeht, diese parameter in form einer hash-ref uebergeben bekommt und nicht jeder parameter einzeln uebergeben wird, dann kann eine partielle umkopiererei aus besagten lesbarkeitsgruenden sinnvoll sein. klar, das erfordert eine gute dokumentation der funktion, aber das erfordert eigentlich ohnehin jede funktion.

              prost
              seth

              1. Tach!

                wenn eine funktion (ich spreche jetzt mal in perl-terminologie, weil ich die von php nicht so gut kenne) von einer komplizierten hash-reference diverse eintraege benoetigt und davon ausgeht, diese parameter in form einer hash-ref uebergeben bekommt und nicht jeder parameter einzeln uebergeben wird, dann kann eine partielle umkopiererei aus besagten lesbarkeitsgruenden sinnvoll sein.

                PHP unterschiedet nicht zwischen Hash, Listen, etc. Das sind alles Arrays. Referenzen als Parameter erzwingen kann es auch nicht. Eine Funktion kann zwar einen Parameter per Referenz übernehmen wollen, aber da reicht völlig aus, wenn es eine Variable ist (und kein berechneter Ausdruck). Eine Variable ist auch ein Array-Element. Wenn also eine Funktion einen Teil von einem Array haben möchte, dann übergebe ich ihr einfach den Teil ($_POST['foo']) und keine Kopie des Teils. In $_POST['foo'] kann beliebiges Zeug stecken, also ein Array oder ein String (alles andere wäre händisch in $_POST eingefügt worden).

                meine antwort zielte auf ausnahmefaelle ab, weil mir deine formulierung zu pauschal war.

                Sie bezog sich ja auch nicht auf alle möglichen Konstellationen, sondern auf das unnötige Umkopieren einfacher $_POST/$_GET-Inhalte in Wald- und Wiesenscripten.

                dedlfix.