Datei speichern ( fopen mit URL-Parameter)


DiePetra

Grünschnabel
Hallo,

erstmal vorweg: Das sind meine ersten Schritte in PHP - seid lieb zu mir :)

Habe HTML-Seite mit HTML-Formular, das mit Javascript verarbeitet wird. Dabei wird
- ein HIDDEN-Input-Feld "CodeJS" gefüllt
- FORM-ACTION bekommt eine PHP-Datei mit 3 URL-Parameter zugewiesen: "datei_schreiben.php?param1=ID,param2=1,param3=inhalte_datei".
- Der SUBMIT wird durch JS ausgelöst

Die URL-Paramter werden im PHP verarbeitet:
Es soll die Datei "outputX.js" in den Ordner "../js/ordnerY/" mit dem Inhalt "inhalte_datei" aus dem HIDDEN-INPUT-Feld geschrieben werden.
Danach soll auf eine HTML-Seite mit Parameter zurück gelinkt werden.

1. Problem: Die Strings werden nicht nicht richtig zusammengesetzt (habs auch mit String-Addintion "." probiert...)
2. Problem: Wenn "param3=inhalte_datei" (generierter Inhalt des HIDDEN-Input) zu groß wird (>2000 Zeichen...) streikt PHP.
Wie können sonst die Daten aus der HTML-Seite / aus dem HTML-Formular in die separate PHP-Seite gelangen?

Javascript: läuft

Stark verkürztes HTML (wie durch Javascript gefüllt):
HTML:
<FORM METHOD="POST" ACTION="datei_schreiben.php?param1=ordner,param2=1,param3=inhalte_datei">
 <P>... Inhalte, Form-Felder....</P>
 <INPUT TYPE="HIDDEN" NAME="CodeJS">
 <INPUT TYPE="BUTTON" NAME="ButtonPruefen" VALUE="Prüfen"> <!-- Löst JS aus, das HIDDEN-Input füllt und SUBMIT auslöst-->
</FORM>
PHP:
PHP:
<?php
    $FolderID = $_GET[param1];
    $DatenNr  = $_GET[param2];
    $DatenJS  = $_GET[param3];

    $DateiJS = fopen("../js/ordner$FolderID/outpu$DatenNr.js", w );
    fwrite ( $DateiJS ,$DatenJS);
    fclose ( $DateiJS );
    header('Location: index.htm?Name=Name, Folder=' . $FolderID   .', Nummer=' .$DatenNr);
exit;
?>
Habe mikr einiges durch googlen zusammen gesucht, aber zusammen funktioniert es nicht :(
Danke Euch!
 

sheel

I love Asm
Hi

der Reihe nach im PHP-Code:

Code:
$FolderID = $_GET[param1];
ist falsch und muss so lauten:
Code:
$FolderID = $_GET['param1'];
Was ist, wenn diese drei GET-Werte (oder zumindest einer davon) einfach nicht gesendet wurden? (Falls die Antwort ist "meine HTML-Seite sendet die immer": Die PHP-Datei kann man auch anders aufrufen). Falls in dem Fall einfach nichts gemacht werden soll, am Anfang Prüfungen wie die einbauen:
Code:
if(!$_GET['param1']) exit(0);
Danach ... welcher String wird wo nicht richtig zusammengesetzt? Beispiele, wie der Inhalt ausschaut, und wie es richtig sein sollte?

Wenn FolderID ein einzelner Name ist, also kein ganzer Pfad mit / usw., sollte das vor Verwendung in fopen zumindest auch überprüft werden. Kiene / drin, nicht gleich ".", nicht gleich "..", usw. ... oder noch viel besser wäre es, keine Werte die von irgendwo gesendet werden als Dateipafde zu verwenden. Erzeugt ungefähr tausend Sicherheitsprobleme. Wofür werden diese Dateien da überhaupt gemacht? Ziemlich sicher gibts eine bessere Lösung.

Das selbe mit DatenNr, prüfen ob es wirklich eine Zahl ist.

Und ... den Pfad hab ich schon oben behandelt, aber das Selbe mit dem Dateiinhalt auch: Du holst dir da freiwillig ein riesiges Sicherheitsproblem auf den Server.
Was passiert, wenn ich die selbe FolderId und DatenNr wie einer deiner Benutzer verwende und dessen Datei damit dann mit meinem Zeug überschreibe?
Was passiert, wenn mein hochgeladener JS-Code Malware ist, ich Links dazu auf zig Stellen verteile, und die Polizei nach Anzeigen dann natürlich deinen Server als Verteiler sieht?
usw.usw.

Zu der Größenbeschränkung der Url noch: Dafür gibt es POST-Requests (statt GET-Requests).
 

DiePetra

Grünschnabel
Hi... und Danke... und WOW - super ausführlich Daaaanke !!

Mit $FolderID = $_GET['param1']; in Hochkommas hat sich das Zusammensetz der Strings erledigt...

Das if(!$_GET['param1']) exit(0); baue ich nich ein... (muus jetzt erstaml mit den Kids in die Sonntags-Sonne )

Ja, $FolderID und $DatenNr sind jeweils nur ein einziges Zeichen und sind vorgegeben.
Die Dateien sollen immer wieder überschrieben werden.
Sicherheit... auwaia... Das Formular wird nur von 1 Person bedient (mein Vater, ist nicht "öffentlich"). Auf Sicherheit möchte ich daher erstmal verzichten - wäre ja froh, wenns überhaupt erstmal lauft. Alles andere später....

Der Inhalt der Datei, die gespeichert werden soll, ist ein assoziatives JavaScript-Array und enthält quasi "Datensätze". Vor SUBMITT wird dieses Array durch JavaScript erzeugt und in ein HIDDEN-Input-Feld geschrieben. Das soll dann ausgelesen und in eine Datei geschrieben Auszug:

Code:
_yKfzN = new Array();
_yKfzN[0] = new Object();
  _yKfzN[0]['yDB'] = ['Kfz','N',3,5,4];

_yKfzN[1] = new Object();
  _yKfzN[1]['XLBx'] = ['Kfz',0,21,1,0,1,0.7,1,4,1];
  _yKfzN[1]['KfzID'] = 0;
  _yKfzN[1]['Log'] = '';
  _yKfzN[1]['Aktiv'] = 2;
  _yKfzN[1]['Fotos'] = 3;
  _yKfzN[1]['Preis'] = '200,00';
  _yKfzN[1]['Marke'] = 'Opel';
  _yKfzN[1]['Modell'] = 'Vectra';
  _yKfzN[1]['Typ'] = 2;
  _yKfzN[1]['Bj_EZ'] =[2,9,1990];
  _yKfzN[1]['ccm'] = 1800;
  _yKfzN[1]['kW'] = 90;
  _yKfzN[1]['km'] = 160000;
  _yKfzN[1]['HU'] = [10,2017];
  _yKfzN[1]['AU'] = [10,2017];
  _yKfzN[1]['Sprit'] = 4; // SELECTED Index-Nr
  _yKfzN[1]['Verbr'] = 0;
  _yKfzN[1]['Co2'] = 2;
  _yKfzN[1]['Gtrb'] = [2,3];
  _yKfzN[1]['else1'] =0;
  _yKfzN[1]['else2'] = 0;
  _yKfzN[1]['else3'] = 0;
  _yKfzN[1]['Text'] = 'Fahrzeug ist in einem für das Baujahr 1990 aber mit rost ';
  _yKfzN[1]['Foto'] = new Array();
  _yKfzN[1]['Foto'][1] = 'Seitenansicht Seitenansicht Seitenansicht';
  _yKfzN[1]['Foto'][2] = 'Frontansicht Frontansicht Frontansicht';
  _yKfzN[1]['Foto'][3] = 'Heckansicht Heckansicht Heckansicht';
  _yKfzN[1]['Foto'][4] = 'Foto 4';
  _yKfzN[1]['Foto'][5] = 'Foto 5';
  _yKfzN[1]['Foto'][6] = 'Foto 6';
  _yKfzN[1]['Foto'][7] = 'Foto 7';
  _yKfzN[1]['Foto'][8] = 'Foto 8';
  _yKfzN[1]['Foto'][9] = 'Foto 9';
  _yKfzN[1]['Foto'][10] = 'Foto 10';

_yKfzN[2] = new Object();
  _yKfzN[2]['XLBx'] = ['Kfz',0,21,1,0,1,0.7,1,4,1];
  _yKfzN[2]['KfzID'] = 0;
  _yKfzN[2]['Log'] = '';
  _yKfzN[2]['Aktiv'] = 1;
  _yKfzN[2]['Fotos'] = 6;
  _yKfzN[2]['Preis'] = '17.000,00';
  _yKfzN[2]['Marke'] = 'Audi';
  _yKfzN[2]['Modell'] = 'A4';
  _yKfzN[2]['Typ'] = 4;
  _yKfzN[2]['Bj_EZ'] = [1,11,2011];
  _yKfzN[2]['ccm'] = 2000;
  _yKfzN[2]['kW'] = 136;
  _yKfzN[2]['km'] = 82000;
  _yKfzN[2]['HU'] = [7,2016];
  _yKfzN[2]['AU'] = [7,2016];
  _yKfzN[2]['Sprit'] = 6;
  _yKfzN[2]['Verbr'] = 0;
  _yKfzN[2]['Co2'] = 2;
  _yKfzN[2]['Gtrb'] = [2,3];
  _yKfzN[2]['else1'] =0;
  _yKfzN[2]['else2'] = 0;
  _yKfzN[2]['else3'] = 0;
  _yKfzN[2]['Text'] = 'Gutes Auto! Gutes Auto!Gutes Auto!Gutes Auto!Gutes Auto!Gutes Auto!';
  _yKfzN[2]['Foto'] = new Array();
  _yKfzN[2]['Foto'][1] = 'Gesamtansicht';
  _yKfzN[2]['Foto'][2] = 'Heckansicht';
  _yKfzN[2]['Foto'][3] = 'Cockpit Cockpit Cockpit';
  _yKfzN[2]['Foto'][4] = 'Schaltung';
  _yKfzN[2]['Foto'][5] = 'Instrumenmte';
  _yKfzN[2]['Foto'][6] = 'Hintere Türvekleidung (wie auch allgemeiner Zustand des Fahrzeugs)';
  _yKfzN[2]['Foto'][7] = 'Fototext 7';
  _yKfzN[2]['Foto'][8] = 'Fototext 8';
  _yKfzN[2]['Foto'][9] = 'Fototext 9';
  _yKfzN[2]['Foto'][10] = 'Fototext 10';

// usw.
Zu der Größenbeschränkung der Url noch: Dafür gibt es POST-Requests (statt GET-Requests).
Das habe ich nicht verstanden :(

Daten, HTML usw. liegen schon lange vor. Jetzt soll alles nur mittels PHP "automatisiert" werden.
Bislang hat mein Vater das Array manuell gefüllt und per FTP hochgeladen. Bei Tippfehlern ging dann natürlich nichts mehr.
Ich weiß... ist alles andere als "professionell", reicht uns aber.

Bin heute nochmal zurück hier... die Kids müssen raus o_O
 
Zuletzt bearbeitet:

sheel

I love Asm
wäre ja froh, wenns überhaupt erstmal lauft.
Versteh ich - aber "über Sicherheit erst später nachdenken" kann auch heißen, später ganz von vorn beginnen zu müssen (oder dafür zu faul sein und es dann bereuen, wenn was passiert ist).
ist nicht "öffentlich"
Wenn das bedeutet "die PHP-Datei kennt sonst niemand, aber sie ist prinzipiell schon aufrufbar", ist das kein nennenswerter Schutz.

...

Zu den Post-Requests, ich seh grad dass dein Formular ja schon Post verwendet - aber trotzdem noch Getparameter auch dabei hat. Die drei Parameter (oder zumindest der eine große) sollten von der Url raus, und auch als hidden Textfeld gesendet werden.
Auf PHP-Seite ist es dann ziemlich einfach umzustellen: $_GET mit $_POST ersetzen, fertig. 2000 oder 200000 sollte dann kein Problem mehr sein (noch ein paar Nuller dazu könnte aber eine Einstellungsänderung im Server nötig machen, es gibt da schon auch ein Limit).
 
Zuletzt bearbeitet:

DiePetra

Grünschnabel
Die PHP-Seite u.a. alles andere liegt hinter einam Server-Passwortschutz ( htacess ). Das muß reichen... Wenn nicht... erzähls nicht meinem Vater :D

Habe es auch schon mit HIDDEN-Felder (also ohne URL-Parameter ) probiert gehabt... hole ich nochmal raus...
Alles andere später.... Daaaaaaaanke erstmal!
 

Technipion

Erfahrenes Mitglied
Hallo DiePetra,
ohje, sheel reitet nicht ohne Grund so sehr auf der Sicherheit des Systems herum :oops:
Außerdem frage ich mich:
Das Formular wird nur von 1 Person bedient (mein Vater, ist nicht "öffentlich").
Lohnt sich dann überhaupt die viele Arbeit? Insbesondere weil
Bislang hat mein Vater das Array manuell gefüllt und per FTP hochgeladen.
es einige Lösungen gibt um die Synchronisation per FTP (und viiieeel besser SFTP) zu automatisieren.
Womöglich gibt es für deine Anwendung bereits ein praktisch fertiges Software-Paket, das nur noch eingerichtet werden muss. Damit könntest du dir Stunden von Arbeit sparen ;)

Gruß Technipion
 

DiePetra

Grünschnabel
Hallo Ihr beiden... da isse wieder.

Technipion:
Du hast damit bestimmt recht - Profis wie Ihr stellen sich da bestimmt die Nackenhaare... Möchte aber erstmal das Thema Sicherheit außer acht lassen. Auch fertige Lösungen etc. ... Für unseren Pillepalle reicht es erstmal so... Alles Weitere mit der Zeit....
Mir machts das Spaß und ich möchte ja (bei Euch) auch was dazu lernen!

sheel:
"SSL / https".... ja, soll auch kommen. "Fail2ban" hab ich eben mal gegoogelt... sieht gut, aus, aber später.... Aber auch dafür Danke! Wenn der Server mal weg ist, na dann isser halt mal weg. Geht auch wieder vorbei.

Ok, bin Deinem Rat gefolgt:
- habe alles mal wieder auf HIDDEN INPUTS umgestellt
- hole mir das PHP-Script mit INCLUDE rein (stimmt das so ???)

Tschuldige... habe es jetzt noch nicht getestet weil ich jetzt nicht weiß, wie ich die INCLUDIERTE PHP-Datei / Funktion starte...: Der Reihe nach :) :

Die HTML-Seite mit Formular:
HTML:
<BODY>
  <?PHP include ("../datei_schreiben.php"); ?>
  <!-- HTMl-Inhalte ................................................ -->
    <FORM METHOD="POST" ACTION="datei_schreiben.php">
        <P>... Inhalte, Form-Felder....</P>
        <INPUT TYPE="HIDDEN" NAME="FolderID">
        <INPUT TYPE="HIDDEN" NAME="DatenNr">
        <INPUT TYPE="HIDDEN" NAME="CodeJS">
        <INPUT TYPE="BUTTON" NAME="ButtonPruefen" VALUE="Prüfen"> <!-- Löst JS aus, das HIDDEN-Input füllt und SUBMIT auslöst-->
    </FORM>
  <!-- ............................ HTMl-Inhalte -->
</BODY>
Frage:
Wie rufe ich da nun die "datei_schreiben.php" aus / wie starte ich die PHP-Datei ???
Das hat beim letzten mal wohl nicht funktioniert :oops:
Der SUBMIT wird im Javascript durch "submit()" ausgelöst und muß ja jetzt irgendwie die PHP-Datei ausführen...?

Die PHP-Datei (im HTML hereingeholt = INCLUDE... ):
PHP:
<?php
   $FolderID = $_GET['FolderID']; // liest Feldinhalt von FORM-INPUT NAME=="FolderID" aus
   $DatenNr  = $_GET['DatenNr'];  // liest Feldinhalt von FORM-INPUT NAME=="DatenNr" aus
   $DatenJS  = $_GET['CodeJS'];   // liest generiertzen Feldinhalt von FORM-INPUT NAME=="CodeJS" aus

   $DateiJS = fopen("../js/ordner$FolderID/outpu$DatenNr.js", w );
    fwrite ( $DateiJS ,$DatenJS);
    fclose ( $DateiJS );
    header('Location: index.htm?Name=Name, Folder=' . $FolderID . ', Nummer=' . $DatenNr);
exit;
?>
 
Zuletzt bearbeitet:

sheel

I love Asm
hole mir das PHP-Script mit INCLUDE rein (stimmt das so ???)
Wieso das denn?

Wie rufe ich da nun die "datei_schreiben.php" aus / wie starte ich die PHP-Datei ???
Das hat beim letzten mal wohl nicht funktioniert :oops:
Der SUBMIT wird im Javascript durch "submit()" ausgelöst und muß ja jetzt irgendwie die PHP-Datei ausführen...?
Das sollte eigentlich gleich wie vorher funktionieren ... zumindest wenn das include da weg ist.
 

ComFreek

Mod | @comfreek
Moderator
PHP:
<?php
   $FolderID = $_GET['FolderID']; // liest Feldinhalt von FORM-INPUT NAME=="FolderID" aus
   $DatenNr  = $_GET['DatenNr'];  // liest Feldinhalt von FORM-INPUT NAME=="DatenNr" aus
   $DatenJS  = $_GET['CodeJS'];   // liest generiertzen Feldinhalt von FORM-INPUT NAME=="CodeJS" aus

   $DateiJS = fopen("../js/ordner$FolderID/outpu$DatenNr.js", w );
    fwrite ( $DateiJS ,$DatenJS);
    fclose ( $DateiJS );
    header('Location: index.htm?Name=Name, Folder=' . $FolderID . ', Nummer=' . $DatenNr);
exit;
?>
Wow, das sieht mir nach vielen Sicherheitslücken aus: Ungeprüfte Interpolation in Dateiname sowie in Weiterleitungs-URI.
Und das 'w' bei fopen sollte in Anführungszeichen stehen. Das sollte eigentlich auch als nicht-fatale Fehlermeldung ins Errorlog geschrieben worden sein.
 

DiePetra

Grünschnabel
Jo hey... es funktioniert fast!

Nur die Datei die geschrieben wurde ist leer ( 0 kB ). Sonst soweit alles gut (echo gibt alle Daten korrekt aus):

PHP:
<?php
 $ArtID = $_POST['ArtID']; // liest Feldinhalt von FORM-INPUT NAME=="KfzArtID" aus
 $SrcDt = $_POST['SrcDt'];   // liest generiertzen Feldinhalt von FORM-INPUT NAME=="KfzSrcDt" aus
 $FileJS   = "../dt.js/test_kfz$ArtID.js";
 $DateiJS = fopen($FileJS, "w" );

 fwrite( $FileJS ,$SrcDt);
 fclose( $FileJS );
exit;
?>
Wenn jetzt noch $KfzSrcDt in die Datei geschrieben wird....
 
Zuletzt bearbeitet:

DiePetra

Grünschnabel
Auwaia... mein Fehler

So läuft es jetzt:
PHP:
<?php
  $ArtID = $_POST['ArtID']; // liest Feldinhalt von FORM-INPUT NAME=="KfzArtID" aus
  $SrcDt = $_POST['SrcDt'];   // liest generiertzen Feldinhalt von FORM-INPUT NAME=="KfzSrcDt" aus
  $FileJS   = "../dt.js/test_kfz$ArtID.js";

 $DateiJS = fopen($FileJS, "w" );
  fwrite( $DateiJS, $SrcDt);
  fclose( $DateiJS);
 exit;
?>
Viiiiiiiiiiiiiiielen lieben Dank an Euch!
Dank auch an sheel für Deine Geduld mit mir!
Will mich jetzt in PHP einarbeiten. Würde mich freuen, wenn Ihr mir da helfen wolltet, wenn ich nicht weiter komme.