Kurosan: uploader anpassen

Guten Tag,
ich möchte einen simplen uploader an meinem online-editor anpassen, nur leider hat bisher nichts geklappt.

So funktioniert das erstellen von Dateien in meinem Script:

        echo '<form method=get action="'.SCRIPT_URI.'">'."\n";  
        echo '<input type="hidden" name="func" value="newfile">'."\n";  
        echo '<input type="hidden" name="dir" value="'.$dir.'">'."\n";  
        echo '<img src="../../pic/clearpixel_1x1.gif" alt="" width="45" height="1" />'."\n";  
        echo '<input style="width:200px;" name="src" type="text" size="50" value="NeueDatei.htm">'."\n";  
        echo '<input type="hidden" name="s_id" value="'.$_GET['s_id'].'">'."\n";  
        echo '<img src="../../pic/clearpixel_1x1.gif" alt="" width="25" height="1" />'."\n";  
        echo '<button type="submit" value="Datei erstellen" class="form">Datei erstellen</button>'."\n";  
        echo '</form>'."\n\n";  
  
if (FUNC=='newfile') {  
        if (!file_exists($basedir.$dir.$src)) {  
          $fp = @fopen($basedir.$dir.$src, "w");  
          if ($fp) {  
                  fclose($fp);  
          echo '<script type="text/javascript" language="Javascript">alert("Datei '.$src.' erfolgreich erstellt!")</script>';  
} else  
          echo '<script type="text/javascript" language="Javascript">alert("Datei '.$src.' konnte nicht erstellt werden!")</script>';  
} else  
          echo '<script type="text/javascript" language="Javascript">alert("Datei '.$src.' existiert bereits!")</script>';;  
  
        DateiManager($basedir,$dir,$src);  
}

und das ist das simple Uploadscript:

<form action=”upload.php” method=”post” enctype=”multipart/form-data”>  
<input type=”file” name=”datei”><br>  
<input type=”submit” value=”Hochladen”>  
</form>  
  
$tempname=$_FILES['datei']['tmp_name'];  
$name=$_FILES['datei']['name'];  
copy($tempname,$name);  
unlink($tempname);

Das Formelement bekomme ich hin........aber den zweiten Teil zum Ausführen bekomme ich einfach nicht angepasst.

Ich hoffe das mir einer helfen kann.

  1. Ich möchte dir auf jeden Fall dies hier ans Herz legen:

    http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc

    Gruß
    Hier her Doc!
    T-Rex

  2. Lieber Kurosan,

    T-Rex hat Dir ja schon einen wertvollen Linktipp gegeben. Lass mich noch auf ein Paar Dinge hinweisen, die Dir das Schreiben von PHP-Scripts etwas vereinfachen/verbessern könnten.

    |         echo '<form method=get action="'.SCRIPT_URI.'">'."\n";  
    
    >         echo '<input type="hidden" name="func" value="newfile">'."\n";  
    >         echo '<input type="hidden" name="dir" value="'.$dir.'">'."\n";  
    >         echo '<img src="../../pic/clearpixel_1x1.gif" alt="" width="45" height="1" />'."\n";
    
    

    Du schreibst jede Menge HTML-Code in Dein PHP-Script. Im Moment mag das noch eine sinnvolle Vorgehensweise für Dich sein, insbesondere, wenn Du alles schön "griffig" in einer einzigen PHP-Datei haben willst. Später wirst Du allerdings bei größeren Projekten schnell merken, dass Dir eine strengere Trennung von Programm-Logik (PHP) und Ausgabeformat (HTML) wesentlich mehr Übersichtlichkeit in Dein Projekt bringen kann. Daher halte ich es für besser, HTML-Dateien anzulegen, in denen der notwendige HTML-Code mit Platzhaltern steht, die Du dann in eine Variable einlesen und "befüllen" kannst. Beispiel:

    <form method="get" action="{script-uri}">  
        <p>  
            <input type="hidden" name="func" value="newfile">  
            <input type="hidden" name="dir" value="{dir}">  
            <img src="../../pic/clearpixel_1x1.gif" alt="" width="45" height="1" />  
            <input style="width:200px;" name="src" type="text" size="50" value="NeueDatei.htm">  
            <input type="hidden" name="s_id" value="{s-id}">  
            <img src="../../pic/clearpixel_1x1.gif" alt="" width="25" height="1" />  
            <input type="submit" value="Datei erstellen" class="form">Datei erstellen</input>  
        </p>  
    </form>
    

    Angenommen Du benutzt für Deine Platzhalter keine einzelnen Variablen, sondern ein Array, dessen Schlüssel Deinen Platzhalter-Variablen entsprechen:

    $fill_values = array (  
        'script-uri' => SCRIPT_URI,  
        'dir' => $dir,  
        's-id' => (isset($_GET['s_id']) ? $_GET['s_id'] : '')  
    );
    

    Nun kannst Du mit einer Schleife den eingelesenen HTML-Code befüllen:

    $html_form = file_get_contents('./templates/uploader-form.html');  
      
    foreach ($fill_values as $key => $value) {  
        $search = sprintf('{%s}', $key);  
        $html_form = str_replace(  
            $search,  
            htmlspecialchars($value),  
            $html_form  
        );  
    }  
      
    echo $html_form;
    

    Eine wasserdichte Fehlerprüfung solltest Du unbedingt auch implementieren. In meinem Code-Beispiel wird nicht sichergestellt, dass $_GET['s_id'] zwingend vorhanden sein muss, es wird im Fehlerfalle mit einem Leerstring weitergearbeitet. Ob das in Deinem Projekt sinnvoll ist, musst Du wissen.

    copy($tempname,$name);

    Was ist hier der Unterschied zu copy($tempname, $name)? Lass die Anführungszeichen weg, sie machen nichts besser, sondern verschleiern im besten Falle nur unnötig! Noch besser wäre natürlich, wenn Du Variablen garnicht erst umkopierst, sondern gleich die Originalvariablen nämest:

    copy($_FILES['datei']['tmp_name'], $_FILES['datei']['name']);

    Was Du hier aber eigentlich tust, ist nichts anderes, als die hochgeladene Datei in Deinen Bereich zu "verschieben". Dafür hat PHP eingens eine Funktion entwickelt: move_uploaded_file(). Daher ergibt sich folgender Einzeiler für Deinen originalen Vierzeiler:

    move_uploaded_file($_FILES['datei']['tmp_name'], $_FILES['datei']['name']);

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Tach!

      Du schreibst jede Menge HTML-Code in Dein PHP-Script. Im Moment mag das noch eine sinnvolle Vorgehensweise für Dich sein, insbesondere, wenn Du alles schön "griffig" in einer einzigen PHP-Datei haben willst. Später wirst Du allerdings bei größeren Projekten schnell merken, dass Dir eine strengere Trennung von Programm-Logik (PHP) und Ausgabeformat (HTML) wesentlich mehr Übersichtlichkeit in Dein Projekt bringen kann.

      Einspruch. Das geht vielleicht bei einfachen Templates mit nur einer Handvoll zu ersetzender Werte gut. Aber irgendwann kommt Logik mit ins Spiel. Beispielsweise soll die Auflistung der Fehlermeldungen nur dann angezeigt werden, wenn es welche gibt. Die Anzahl der Datensätze aus dem DBMS ist dem Template-Ersteller nicht bekannt. Schlimmer noch, sie ist variabel. Man benötigt da also eine Schleifenkonstruktion, um alle zu berücksichtigen. Eine Antwort auf solche Szenarien sind Blöcke, die man gezielt aufnehmen oder weglassen kann. Dann ist man bei reinen HTML-Templates schnell bei einer mehr oder weniger komplexen Hilfssysntax, und einem ebensolchen System, das diese auswerten kann. Das kann man so machen, und da gibts auch vorgefertigte Systeme.

      Einfacher ist es, nicht PHP und HTML zu trennen, sondern Verarbeitungslogik von Darstellungslogik. Das Darstellungslogik kann dann wie der Rest des Systems PHP verwenden, was ja bereits selbst eine Template-Sprache ist. Der Fehlermeldungsblock kann zum Beispiel so notiert werden:

      <?php if ($errors): ?>  
      <ul>  
        <?php foreach($errors as $error): ?>  
        <li><?= htmlspecialchars($error) ?></li>  
        <?php endforeach ?>  
      </ul>  
      <?php endif ?>
      

      Der Code geht von PHP 5.4 aus, in dem <?= als Kurzform für <?php echo unausschaltbar enthalten ist. Wenn man der eigenen Herr über die Anwendung und dem Konfigurationswert short_open_tag ist und keine Kompatibilität mit anderen nicht beeinflussbaren Einstellungen benötigt, kann man auch noch die <?php zu <? abkürzen.

      $search = sprintf('{%s}', $key);
          $html_form = str_replace(
              $search,
              htmlspecialchars($value),
              $html_form
          );

      sprintf() bringt hier keinen wirklichen Vorteil. Eine Klammer vor und nach einem Wert zu setzen, geht vergleichsweise übersichtlich und einfach in der Stringverkettungssyntax ... str_replace('{' . $key . '}', htmlspecialchars( ...

      Eine wasserdichte Fehlerprüfung solltest Du unbedingt auch implementieren. In meinem Code-Beispiel wird nicht sichergestellt, dass $_GET['s_id'] zwingend vorhanden sein muss, es wird im Fehlerfalle mit einem Leerstring weitergearbeitet.

      Genauer: null (was im String-Kontext zu einem Leerstring wird) und eine normalerweise unterdrückte Notice-Meldung. Dise Notice-Meldungen sind aber ein wichtiges Hilfsmittel beim Entwickeln der Anwendung, zeigen sie einem doch, wo man auf etwas zuzugreifen versucht, was gar nicht da ist. Das kann durchaus ein Fehler und nicht immer gewolltes Verhalten sein. Deshalb empfiehlt es sich, mit auf E_ALL gestelltem error_reporting zu entwickeln und allen Notice-Meldungen auf den Grund zu gehen.

      copy($tempname,$name);
      Was ist hier der Unterschied zu copy($tempname, $name)? Lass die Anführungszeichen weg, sie machen nichts besser,

      Zumal das auch noch typografische Anführungszeichen und nicht die benötigten " sind.

      Daher ergibt sich folgender Einzeiler für Deinen originalen Vierzeiler:

      Der dann allerdings wieder zu einem Mehrzeiler ergänzt werden muss, wenn man Fehlerzustände ordentlich abfangen will.

      dedlfix.

    2. Danke Felix Riesterer.
      ich werde mich erstmal daran setzen und das ganze Script auf die Methode umstellen.

      Das ganz grosse Problem ist das das Script eine s_id via GET mitsendet,
      aber der Uploader mit POST arbeitet.
      Auch erkennt das Script den Dateipfad, was das Uploadscript nicht macht.

      Aber erstmal das Script umschreiben so wie erklärt, ist wesentlich sauberer als meine Arbeit(zusammengefercht aus Tutorials).

      Jede weitere Hilfe nehme ich gerne an.

      1. Tach!

        Das ganz grosse Problem ist das das Script eine s_id via GET mitsendet, aber der Uploader mit POST arbeitet.

        Das ist grundsätzlich kein Problem. $_GET ist etwas missverständlich aber dafür einfach benannt. In $_GET landet alles, was im Querystring enthalten ist. Und solch ein Querystring kann auch in POST-Requests an die URL gehängt werden. Das heißt, auch in POST-Request können Werte in $_GET landen.

        Weiterhin sollte es kein Problem sein, den Wert in einem mit POST zu versendenen Formular als Hidden-Input-Feld zu notieren, dann landet er ebenfalls mit in $_POST.

        Auch erkennt das Script den Dateipfad, was das Uploadscript nicht macht.

        "Erkennen" ist nicht das richtige Wort. Sowas passiert ja nicht aufgrund von Intelligenz im Rechner. Entweder es ist Code da, der Werte nach bestimmten Regeln bildet oder nicht. Die Prinzipien dieses Codes kann man jedenfalls für eigene Anforderungen wiederverwenden. - Soweit die Theorie. Inwieweit damit ein Anfänger zurecht kommt, steht auf einem anderen Blatt.

        dedlfix.

      2. Lieber Kurosan,

        Das ganz grosse Problem ist das das Script eine s_id via GET mitsendet,
        aber der Uploader mit POST arbeitet.

        was stört Dich an dieser Variante?

        <form method="get" action="{script-uri}?s_id={s-id}">

        Das, was in einer URL nach dem Fragezeichen steht, also name-value-Paare wie a=1&b=2&c=3 landen in der superglobalen Variable $_GET. Du hast also in Deinem Script sowohl im $_POST- als auch im $_GET-Array Sachen drin stehen. Nutze sie!

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
        1. Tach!

          was stört Dich an dieser Variante?
          <form method="get" action="{script-uri}?s_id={s-id}">

          Die geht so nicht. Der Browser verwirft bei method=GET den Querystring und hängt stattdessen die Felder des Formulars an den {script-uri}-Teil. Nur bei method=POST bleibt der Querystring erhalten. Vielleicht meintest du das ja mit POST.

          dedlfix.

          1. Lieber dedlfix,

            <form method="get" action="{script-uri}?s_id={s-id}">
            Vielleicht meintest du das ja mit POST.

            richtig! So muss es lauten: <form method="post" action="{script-uri}?s_id={s-id}">

            Liebe Grüße,

            Felix Riesterer.

            --
            ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    3. Lieber Felix Riesterer,
      wie schon gesagt ihre Erklärungen sind sehr verständlich.
      Allerdings habe ich bisher immer alles in einem Script untergebracht,damit kommt leider eine neu Frage auf.

      1. Ist es möglich das die (php-Datei)editor.php aufgerufen wird und die editor.html einbindet?
         Denn dann könnte ich sämtlichen php code auslagern wenn es die Möglichkeit gibt

      2. Wenn es möglich ist, wie übergebe sowas z.B:
         ~~~php         $dirs = explode("/", $dir);
              $entries=count($dirs)-1;
              echo '<td><h2>';
              echo '<a href="'.SCRIPT_URI.'?dir='.$dir.'&s_id='.$_GET["s_id"].'&id='.$row->id.'"><img src="img/refresh.png" width="18" height="18" alt="Seite neu laden" title="Seite neu laden" border="0" style="margin-left:20px;margin-right:20px"></a>';
              echo '<a href="'.SCRIPT_URI.'?s_id='.$_GET["s_id"].'&id='.$row->id.'">'.$_SERVER['HTTP_HOST'].'</a>/';

      $dirss[0]=$dirs[0]."/";
          for($i=1 ; $i<$entries; $i++) { $dirss[$i]=$dirss[$i-1].$dirs[$i]."/"; }
          for($i=0 ; $i<$entries-1; $i++) {
              echo '<a href="'.SCRIPT_URI.'?dir='.$dirss[$i].'&s_id='.$_GET["s_id"].'&id='. $row->id .'">'.$dirs[$i].'</a>/';
              }
              echo $dirs[$i].'/<br></h2></td>';
              echo '</tr>';
              echo '</table>';

      bezogen auf genau diesen Teil:  
      `        echo $dirs[$i].'/<br></h2></td>';`{:.language-php}  
      von der php-Datei an die htlm-Datei  
        
      Stimmt ich könnte auch sämtliche Handbücher durchlesen, aber leider nicht verstehen, da mir dazu leider das Verständniss fehlt zuerfassen was genau gemeint ist...Was Anhand dieses Scripts und euren Erklärungen genau anders ist....Die Vorgänge werden verständlich.  
      Ich hoffe ihr helft mir weiter, auch wenn ich so viele Fragen habe.  
        
      Ihr seit echt gute Leute und eure bisherige Hilfe war super.(Muss mal gesagt werden)
      
      1. Tach!

        1. Ist es möglich das die (php-Datei)editor.php aufgerufen wird und die editor.html einbindet?

        Ja. readfile(), wenn die Datei nur ausgegeben werden muss, und require/include, wenn darin Code auszuführen ist.

        Denn dann könnte ich sämtlichen php code auslagern wenn es die Möglichkeit gibt

        Fang erstmal an, deine Programmlogik nach dem EVA-Prinzip zu sortieren: Eingabe-Verarbeitung-Ausgabe. Der ingabe-Teil ist oft recht kurz oder nicht vorhanden. Der V-Teil ist der wichtigste. Der sammelt deine Daten zusammen oder schreibt sie in die Datenhaltung. Am Ende stehen jedenfalls alle für die Ausgabe benötigten Werte fest, vielleicht sogar in einer einzigen Struktur, aber auch mehrere Variablen sind völlig ok - vor allem bei kleineren, leicht überschaubaren Projekten. Der A-Teil fügt nun die statischen Teile mit den variablen Teilen aus dem V-Teil zusammen und erzeugt so den im Browser ankommenden Code. Wie schon gesagt, kann auch im A-Teil noch Logik enthalten sein, denn eine Tabelle oder eine Liste erfordert üblicherweise eine Schleifenkonstruktion und bedingt auszugebende Teile eine Fallunterscheidung (if).

        1. Wenn es möglich ist, wie übergebe sowas z.B:
                  echo '<a href="'.SCRIPT_URI.'?dir='.$dir.'&s_id='.$_GET["s_id"].'&id='.$row->id.'"><img src="img/refresh.png" width="18" height="18" alt="Seite neu laden" title="Seite neu laden" border="0" style="margin-left:20px;margin-right:20px"></a>';
                  echo '<a href="'.SCRIPT_URI.'?s_id='.$_GET["s_id"].'&id='.$row->id.'">'.$_SERVER['HTTP_HOST'].'</a>/';

        Die variablen Teile sind hier die URL. Diese sollte im V-Teil vollständig zusammengebaut werden. Beachte dabei den Kontextwechsel. Du fügst Daten in den Querystring-Teil einer URL ein, also musst du dessen Regeln beachten. Und wenn du die fertige URL im A-Teil ausgibst, musst du auch noch den Kontext HTML beachten.

        $dirss[0]=$dirs[0]."/";
            for($i=1 ; $i<$entries; $i++) { $dirss[$i]=$dirss[$i-1].$dirs[$i]."/"; }
            for($i=0 ; $i<$entries-1; $i++) {
                echo '<a href="'.SCRIPT_URI.'?dir='.$dirss[$i].'&s_id='.$_GET["s_id"].'&id='. $row->id .'">'.$dirs[$i].'</a>/';
                }
                echo $dirs[$i].'/<br></h2></td>';
        bezogen auf genau diesen Teil:
        echo $dirs[$i].'/<br></h2></td>';
        von der php-Datei an die htlm-Datei

        Erstmal steht diese Ausgabe außerhalb der Schleife(n). Das $i ist zu dem Zeitpunkt immer gleich dem Wert von $entries. Wenn das so sein soll, nimm gleich $entries. - Ansonsten, $dirs wird im V-Teil erzeugt, an den A-Teil weitergegeben (beziehungsweise steht als Variable im Speicher und wird von A einfach so genutzt). Der A-Teil iteriert dann in foreach darüber, denn die Schleifenvariable $i respektive die Keys des Arrays brauchst du ja nicht.

        Stimmt ich könnte auch sämtliche Handbücher durchlesen, aber leider nicht verstehen, da mir dazu leider das Verständniss fehlt zuerfassen was genau gemeint ist...

        Weißt du, warum die Großmutter vom Teufel gestorben ist? Wenn einem das Verständnis fehlt, dann ist das eine sehr schlechte Voraussetzung für die zu erledigenden Tätigkeiten. Wenn sich bei dir das Verständnis aber im Allgemeinen nach Aneignung des nötigen Wissens einstellt, dann ist das im Prinzip alles nur eine Frage des Fleißes, sich dieses Wissen zu erarbeiten.

        Was Anhand dieses Scripts und euren Erklärungen genau anders ist....Die Vorgänge werden verständlich.

        Dann bist du also noch mehr in der Phase, wo du mehr Tutorials als technische Dokumentation benötigst. Es hilft aber nichts, einen Bogen um die vermeintlich unverständliche Literatur zu machen, denn das wird letztlich dein Nachschlagewerk werden, und deshalb solltest du dich auch da einarbeiten.

        Ich hoffe ihr helft mir weiter, auch wenn ich so viele Fragen habe.

        Na klar.

        dedlfix.