FORM-tag behindert mein JS!
Abbadon
- javascript
0 ChrisB0 Abbadon0 Felix Riesterer0 Abbadon0 Felix Riesterer
Hi (nochmals),
Also ich hab jetzt ein Kontaktformular gechrieben, bei dem automatisch ein div-tag länger wird, wenn man ein Feld ausfüllt, welches ausgefüllt werden muss. Jetzt funktioniert das alles, nur habe ich gemerkt: du hast vergessen den FORM-tag ausenrum zu machen. Und seitdem funktioniert es bei manchen feldern nicht mehr. Genauer gesagt: die Radio-buttons funktionieren und das Feld wo man seine E-Mail-adresse eingeben muss funktioniert auch! Ich habe die JS-Funktionen, welche ich dafür benutzt habe alle immer kopiert und dann bearbeitet, also ist ein rechtschreibfehler auszuschliesen(zumal es vorher auch ging und wenn ich den FORM-tag entferne geht es auch wieder wunderbar).
Wenn es notwendig ist, setze ich hier gerne den Quelltext rein, aber weil der nicht gerade kurz ist, will ich erst auf eine anfrage warten...
Hi,
Also ich hab jetzt ein Kontaktformular gechrieben, bei dem automatisch ein div-tag länger wird, wenn man ein Feld ausfüllt, welches ausgefüllt werden muss.
Es geht also nach wie vor um deinen Fortschrittsbalken?
Jetzt funktioniert das alles, nur habe ich gemerkt: du hast vergessen den FORM-tag ausenrum zu machen. Und seitdem funktioniert es bei manchen feldern nicht mehr. Genauer gesagt: die Radio-buttons funktionieren und das Feld wo man seine E-Mail-adresse eingeben muss funktioniert auch! Ich habe die JS-Funktionen, welche ich dafür benutzt habe alle immer kopiert und dann bearbeitet, also ist ein rechtschreibfehler auszuschliesen(zumal es vorher auch ging und wenn ich den FORM-tag entferne geht es auch wieder wunderbar).
Alles wunderbar schwammig - da kann sich vermutlich kein Mensch drunter vorstellen, wie das Problem wirklich aussieht.
Wenn es notwendig ist, setze ich hier gerne den Quelltext rein, aber weil der nicht gerade kurz ist, will ich erst auf eine anfrage warten...
Etwas relevanten Quelltext wirst du wohl bereitstellen muessen; Betonung liegt auf *etwas* - bitte kuerze das Ganze so weit wie moeglich, so dass das Problem mit einem Minimum an Code nachvollziehbar wird.
Und ein Online-Beispiel ist idR. auch was Feines.
MfG ChrisB
jap geht immernoch um den!.
ok hier mal ein grober ausschnitt des problems:
<FORM method="post" action="index.php?section=Auftragen&do=senden">
<TABLE border="0" align="center" width="550px" cellpadding="0" cellspacing="0">
<TR>
<TD>*</TD>
<TD>VORNAME:</TD>
<TD><INPUT type="text" size="25" name="vorname" onchange="vorname()"></TD>
</TR>
<TR>
<TD></TD>
<TD>AUSGEFÜLLTE PFLICHTFELDER:</TD>
<TD><DIV style="height:20px;width:170px; float:left;"><INPUT type="text" name="fb" style="height:20px; width:<?php if(isset($_GET['paket']) AND isset($paket[$_GET['paket']])) { echo '12.5%'; } else { echo '0%'; }?>; background-Color:red; border:0px;" readonly></DIV><INPUT type="text" style="color:red;" value="<?php if(isset($_GET['paket']) AND isset($paket[$_GET['paket']])) { echo '12.5%'; } else { echo '0%'; }?>" name="fb" size="5" style="border:0px;float:left; height:20px;background:transparent;color:blue;" readonly></TD>
</TR>
<TR>
<TD></TD>
<TD><INPUT type="submit" value="SENDEN" name="senden" onMouseOver="senden()"/></TD>
<TD></TD>
</TR>
</TABLE>
</FORM>
und hier die JS:
function vorname() {
if(document.getElementsByName("vorname")[0].value != "" && vn == 0) {
n = n + 1;
vn = 1;
} else if(document.getElementsByName("vorname")[0].value == "" && vn == 1) {
n = n - 1;
vn = 0;
}
document.getElementsByName("fb")[0].style.width = n*12.5 + "%";
document.getElementsByName("fb")[1].value = n*12.5 + "%";
if(document.getElementsByName("fb")[0].style.width == "0%") {
document.getElementsByName("fb")[0].style.backgroundColor = "red";
document.getElementsByName("fb")[1].style.color = "red";
} else if(document.getElementsByName("fb")[0].style.width == "50%") {
document.getElementsByName("fb")[0].style.backgroundColor = "orange";
document.getElementsByName("fb")[1].style.color = "orange";
} else if(document.getElementsByName("fb")[0].style.width == "75%") {
document.getElementsByName("fb")[0].style.backgroundColor = "#0000FF";
document.getElementsByName("fb")[1].style.color = "#0000FF";
} else if(document.getElementsByName("fb")[0].style.width == "100%") {
document.getElementsByName("fb")[0].style.backgroundColor = "green";
document.getElementsByName("fb")[1].style.color = "green";
}
}
function senden() {
if(document.getElementsByName("fb")[0].style.width != "100%") {
alert("SIE HABEN NOCH NICHT ALLE PFLICHTFELDER AUSGEFÜLLT");
}
}
Lieber Abbadon,
> document.getElementsByName("fb")[0].style.width = n*12.5 + "%";
> document.getElementsByName("fb")[1].value = n*12.5 + "%";
> if(document.getElementsByName("fb")[0].style.width == "0%") {
> document.getElementsByName("fb")[0].style.backgroundColor = "red";
> document.getElementsByName("fb")[1].style.color = "red";
> } else if(document.getElementsByName("fb")[0].style.width == "50%") {
> document.getElementsByName("fb")[0].style.backgroundColor = "orange";
> document.getElementsByName("fb")[1].style.color = "orange";
> } else if(document.getElementsByName("fb")[0].style.width == "75%") {
> document.getElementsByName("fb")[0].style.backgroundColor = "#0000FF";
> document.getElementsByName("fb")[1].style.color = "#0000FF";
> } else if(document.getElementsByName("fb")[0].style.width == "100%") {
> document.getElementsByName("fb")[0].style.backgroundColor = "green";
> document.getElementsByName("fb")[1].style.color = "green";
> }
bei dieser Schreibweise bekommt man ja Zustände! Schreibe das doch als eine http://de.selfhtml.org/javascript/sprache/bedingt.htm#switch@title=switch-Anweisung!
Liebe Grüße aus Ellwangen,
Felix Riesterer.
1. Ist Javascript ein neues Gebiet für mich
2. Habe ich alles einfach kopiert, werte geändert und jetzt alles als switch-abfrage zu schreiben, wäre nochmal mehr aufwand, aber trotzdem danke für den tipp, werde es das nächste mal versuchen
...
Das ganze hilft mir aber trotzdem leider nicht bei meinem Problem
Lieber Abbadon,
und jetzt alles als switch-abfrage zu schreiben, wäre nochmal mehr aufwand, aber trotzdem danke für den tipp, werde es das nächste mal versuchen
das ist sehr schnell gemacht:
var fb = document.getElementsByName("fb");
fb[0].style.width = n*12.5 + "%";
fb[1].value = n*12.5 + "%";
switch (fb[0].style.width) {
case "0%":
fb[0].style.backgroundColor = "red";
fb[1].style.color = "red";
break;
case "50%":
fb[0].style.backgroundColor = "orange";
fb[1].style.color = "orange";
break;
case "75%":
fb[0].style.backgroundColor = "#0000FF";
fb[1].style.color = "#0000FF";
break;
case "100%":
fb[0].style.backgroundColor = "green";
fb[1].style.color = "green";
break;
}
Zu Testzwecken solltest Du prüfen, ob "n" tatsächlich verschiedene Werte annimmt, denn sonst hast Du immer denselben width-Wert und die Fallunterscheidung reagiert natürlich darauf immer identisch.
Das ganze hilft mir aber trotzdem leider nicht bei meinem Problem
Wenn Du Dir nicht helfen lassen willst, dann beschwere Dich gefälligst nicht! Du darfst aber gerne genauer beschreiben, was "funktioniert" und "funktioniert nicht" im Detail bedeuten...
Liebe Grüße aus Ellwangen,
Felix Riesterer.
Wenn Du Dir nicht helfen lassen willst, dann beschwere Dich gefälligst nicht!
Ich beschwere mich doch garnicht. Ich habe doch sogar mich für den Tipp bedankt. Aber so wie ich das sehen, ist dies einfach nur eine vereinfachte schreibweise, aber sie wird mir höchstwahrscheinl. nicht bei meinem Problem helfen, weil mit der schreibweise, welche ich habe, hatte es ja funktioniert, bis ich den <FORM> eingebaut habe.
Lieber Abbadon,
Dein Konzept hinkt (anscheinend). Wenn ich mit der Maus auf den Absende-Button gehe, wird mir eventuell ein Alert angezeigt, den ich mit der Leertaste weg bekomme, um dann eben doch Dein Formular abzuschicken. Welchen Sinn sollte also Deine Überprüfung mit JavaScript haben, wenn ich sie umgehen kann? Es ist ja nett, dass Du die Vollständigkeit der Angaben mittels eines Fortschrittbalkens anzeigen lassen möchtest, jedoch denke ich, dass Du eine serverseitige Überprüfung als vorrangig einsetzen solltest.
Nun sehe ich zwar viel PHP-Code in dem von Dir geposteten HTML, jedoch ist er absolut nich leicht zu überblicken, sehr wahrscheinlich unvollständig, und ohne die gesamte Arbeitsweise Deines PHP-Scriptes zu kennen, kann ich auch nicht abschätzen, was "funktioniert nicht" in Deinem Falle genau bedeutet. Du weigerst Dich ja auch weiterhin, eventuelle Fehlermeldungen der JavaScript-Konsole zu nennen, geschweige denn Fehler, die Dein PHP-Script ausgibt. Du erwähnst ja noch nichteinmal, in welchem Browser es wo wie nicht so klappt, wie Du Dir das vorstellst!
Von daher kann ich nicht wissen, was Du jetzt genau erwartest, und was aber stattdessen passiert... und daher ist Dir nicht zu helfen!
Liebe Grüße aus Ellwangen,
Felix Riesterer.
ich benutze opera, ok javascript meldet keine fehlermeldung. ich werde mal einfach mal die ganze datei online stellen.
<?php
if(isset($_GET['do']) AND $_GET['do'] == "b_senden") {
sql_insert("beauftragen","GESCHLECHT, VORNAME, NACHNAME, PASSWORT, EMAIL, TELEFON, KONTAKTAUFNAME, WUNSCH","".$_POST['geschlecht'].",".$_POST['vorname'].",".$_POST['nachname'].",".$_POST['pw1'].",".$_POST['mail'].",".$_POST['paket'].",".$_POST['kontaktieren'].",". nl2br($_POST['wunsch'])."");
?>
<H2>AUFTRAGUNG SENDEN</H2>
<?php
if(sql_insert) {
echo "Ihr Auftrag wurde erfolgreich gesendet.";
} else {
daten_error();
}
} else {
$paket = array();
$paket[1] = "STARTER";
$paket[2] = "STANDART";
$paket[3] = "EXCLUSIV";
?>
<script type="text/javascript">
var n, g, vn, nn, pwa, pwb, em, p, k;
n = <?php if(isset($_GET['paket']) AND isset($paket[$_GET['paket']])) { echo 1; } else { echo 0; }?>;
g = 0;
p = <?php if(isset($_GET['paket']) AND isset($paket[$_GET['paket']])) { echo 1; } else { echo 0; }?>;
vn = 0;
nn = 0;
pwa = 0;
pwb = 0;
em = 0;
k = 0;
</script>
<H2>AUFTRAGUNGS-FORMULAR<?php if(isset($_GET['paket'])){ echo " - ".$paket[$_GET['paket']]; }?></H2>
<FORM method="post" action="index.php?section=Auftragen&do=senden">
<TABLE border="0" align="center" width="550px" cellpadding="0" cellspacing="0">
<TR valign="top">
<TD>*</TD>
<TD>GESCHLECHT</TD>
<TD><INPUT type="radio" name="geschlecht" value="mann" onchange="geschlechtm()">MANN | <INPUT type="radio" name="geschlecht" value="frau" onchange="geschlechtw()">FRAU</TD>
</TR>
<TR>
<TD>*</TD>
<TD>VORNAME:</TD>
<TD><INPUT type="text" size="25" name="vorname" onchange="vorname()"></TD>
</TR>
<TR>
<TD>*</TD>
<TD>NACHNAME:</TD>
<TD><INPUT type="text" size="25" name="nachname" onchange="nachname()"></TD>
</TR>
<TR>
<TD>*</TD>
<TD>PASSWORT:</TD>
<TD><INPUT type="password" size="25" name="pw1" onchange="pw1()"></TD>
</TR>
<TR>
<TD>*</TD>
<TD>PASSWORT WIEDERHOLEN:</TD>
<TD><INPUT type="password" size="25" name="pw2" onchange="pw2()"></TD>
</TR>
<TR>
<TD>*</TD>
<TD>E-MAIL ADRESSE:</TD>
<TD><INPUT type="text" size="25" name="mail" onchange="email()"></TD>
</TR>
<TR>
<TD>*</TD>
<TD>PAKETAUSWAHL:</TD>
<TD><INPUT type="radio" name="paket" value="starter" onchange="paket_1()" <?php if($_GET['paket'] == 1) { echo "checked=\"checked\"";}?> <?php if($_GET['paket'] == 2 OR $_GET['paket'] == 3) { echo "disabled=\"disabled\"";}?>>STARTER | <INPUT type="radio" name="paket" value="standart" onchange="paket_2()" <?php if($_GET['paket'] == 2) { echo "checked=\"checked\"";}?> <?php if($_GET['paket'] == 1 OR $_GET['paket'] == 3) { echo "disabled=\"disabled\"";}?>>STANDART | <INPUT type="radio" name="paket" value="exclusiv" onchange="paket_3()" <?php if($_GET['paket'] == 3) { echo "checked=\"checked\"";}?> <?php if($_GET['paket'] == 1 OR $_GET['paket'] == 2) { echo "disabled=\"disabled\"";}?>>EXCLUSIV</TD>
</TR>
<TR>
<TD>*</TD>
<TD>ERSTE KONTAKTAUFNAME PER:</TD>
<TD><INPUT type="radio" name="kontaktieren" value="telefon" onchange="kontakt_1()">TELEFON | <INPUT type="radio" name="kontaktieren" value="email" onchange="kontakt_2()">E-MAIL</TD>
</TR>
<TR>
<TD></TD>
<TD valign="top">WÜNSCHE</TD>
<TD><TEXTAREA rows="5" cols="25" name="wunsch" onFocus="if(this.value == 'WENN SIE ERWEITERUNGEN HABEN WOLLEN, HIER KÖNNT IHR ES REINSCHREIBEN.') { this.value='';}">WENN SIE ERWEITERUNGEN HABEN WOLLEN, HIER KÖNNT IHR ES REINSCHREIBEN.</TEXTAREA></TD>
</TR>
<TR>
<TD></TD>
<TD>AUSGEFÜLLTE PFLICHTFELDER:</TD>
<TD><DIV style="height:20px;width:170px; float:left;"><INPUT type="text" name="fb" style="height:20px; width:<?php if(isset($_GET['paket']) AND isset($paket[$_GET['paket']])) { echo '12.5%'; } else { echo '0%'; }?>; background-Color:red; border:0px;" readonly></DIV><INPUT type="text" style="color:red;" value="<?php if(isset($_GET['paket']) AND isset($paket[$_GET['paket']])) { echo '12.5%'; } else { echo '0%'; }?>" name="fb" size="5" style="border:0px;float:left; height:20px;background:transparent;color:blue;" readonly></TD>
</TR>
<TR>
<TD></TD>
<TD><INPUT type="submit" value="SENDEN" name="senden" onMouseOver="senden()"/></TD>
<TD></TD>
</TR>
</TABLE>
</FORM>
<?php
}
?>
Lieber Abbadon,
ich werde mal einfach mal die ganze datei online stellen.
das war nix. Bitte poste einen Link zu einer Testseite, in der man das von Dir Gewünschte betrachten und untersuchen kann. Sollte es sich um ein Problem mit JavaScript handeln, dann lässt sich das schön im Browser betrachten.
Der von Dir gepostete Quelltext ist noch unübersichtlicher, als vorher. Es wäre sinnvoll gewesen, das HTML-Dokument einer fertig an den Browser ausgelieferten Seite zu posten/verlinken. Der PHP-Code stört nur! Wichtig ist nur das, was tatsächlich im Browser ankommt!
Desweiteren bist Du nach wie vor anscheinend nicht in der Lage, genau zu beschreiben, welche Erwartungen Du an Deine Seite hast, und wie sie genau nicht erfüllt werden, bzw. welche Teilerfolge vielleicht erreicht werden.
Ich beende meine Teilnahme an diesem Thread, da ich keine Lust mehr habe. Ich wünsche Dir aber noch viel Erfolg beim Formulieren Deines Problems, damit vielleicht andere Dir weiterhelfen können. Viel Glück!
Liebe Grüße aus Ellwangen,
Felix Riesterer.
Also ich finde ich habe das am anfang ausführlich genug geschrieben. Die seite ist zurzeit offline.
Aber ich werde gern nochmal versuchen das problem zu verdeutlichen.
ich habe 8 Fragen die man ausfüllen muss und zwar:
-GESCHLECHT
-VORNAME
-NACHNAME
-PASSWORT
-PASSWORT WIEDERHOLEN
-PAKET
-KONTAKTAUFNAHME
-E-MAIL-ADRESSE
hierbei sind GESCHLECHT, PAKET und KONTAKTAUFNAME zum auswählen. Die anderen sind Textfelder. Ich will das sich ein DIV-BALKEN in der breite ändert, wenn man einen dieser Fragen beantwortet. Alles funktioniert. Das ganze steht in einer Tabelle. Jetzt habe ich um die Tabelle einen <FORM>-Tag geschrieben (logisch, da es ja ein kontaktformular werden soll). Nur wenn seit dem funktioniert das Script bei Vorname, Nachname, Passwort und Passwort Wiederholen nicht mehr. Wenn ich den <FORM>-Tag wieder lösche, funktioniert alles wieder.
Ich freue mich über Antworten, in welchen eine Theorie drin steht, wo die Ursache des Problem sein könnte.
Vielen Dank im voraus
Hi,
Also ich finde ich habe das am anfang ausführlich genug geschrieben. Die seite ist zurzeit offline.
Dieser Umstand interessiert uns ue-ber-haupt nicht.
Dann stelle gefaelligst eine Testseite irgendwo online zur Verfuegung!
Und dass PHP-Code bei der Diskussion eines clientseitigen Problems absolut nichts zu suchen hat, wurde hier auch schon x-fach erwaehnt - und sollte einem halbwegs logisch denkenden Menschen auch von selbst klar sein.
Der Client bekommt keinen PHP-Code zu sehen - also warum zeigst du ihn *uns*?
_Wenn_ jemand deinen geposteten Code per Copy&Paste uebernehmen wuerde[1] und ihn im Browser testen wollte, ginge das entweder nur mit ungeparstem PHP, was dem Browser jede Menge unverstaendliche <?php>-Tags praesentieren wuerde - oder hoechstvermutlich mit vielen PHP-Fehlern, weil uns deine Daten, die dein Script verarbeiten moechte, nicht vorliegen.
[1] Nein, das will keiner. *Du* willst Hilfe von uns, also halte den Aufwand fuer uns so niedrig wie moeglich - und stelle endlich eine vollstaendige Testseite zur Verfuegung. Himmelherrgottkruzifixsakramentnochmal.
Ich freue mich über Antworten, in welchen eine Theorie drin steht, wo die Ursache des Problem sein könnte.
Die Ursache fuer unser derzeitiges Kommunikationsproblem liegt darin, dass du dich so ungeschickt wie nur eben moeglich beim Problembeschreiben anstellst.
Lies bitte die Tipps für Fragende, und liefere dann endlich mal eine *brauchbare* Problembeschreibung.
MfG ChrisB
Grundlage für Zitat #892.
Hi leute,
Ich danke für die bemühungen, aber leider hänge ich mit der Homepage eh schon ziemlich weit hintendran.(Sie sollte eigentl. schon ende letzten Jahres fertig sein.) Ich habe leider keine Zeit, auch wenn es wohl ein geringer aufwand wäre, eine Testseite daraus zu machen und online zu stellen. Dieses eine Script hat mich Tage gekostet, die ich besser sinnvoller genutzt hätte. Voraussichtlich werde ich dieses Script irgendwann mal versuchen durchzubringen und dann hoffe ich, stelle ich mich besser an bei der Problemstellung und werde dementsprechend auch die Mittel zur verfügung stellen.
Ich möchte mich aber trotzdem für eure Hilfe und bemühungen bedanken, auch wenn ich leider das Problem nicht in den Griff bekommen habe, habe ich doch ein wenig mehr über JavaScript gelernt.
Mit freundlichen Grüßen
Abbadon
Hi Abbadon,
if(isset($_GET['do']) AND $_GET['do'] == "b_senden") {
sql_insert(
"beauftragen",
"GESCHLECHT, VORNAME, NACHNAME, PASSWORT, EMAIL, TELEFON, KONTAKTAUFNAME, WUNSCH",
"".$_POST['geschlecht'].",".$_POST['vorname'].",".$_POST['nachname'].",".$_POST['pw1'].",".$_POST['mail'].",".$_POST['paket'].",".$_POST['kontaktieren'].",". nl2br($_POST['wunsch']).""
);
// [...]
}
Ich weiß ja nicht, was deine Funktion sql\_insert() machen will, aber das sieht mir sehr stark nach einer Sicherheitslücke gegenüber [SQL-Injektionen](http://de.wikipedia.org/wiki/SQL-Injektion) aus.
Was erhoffst du dir eigentlich von dem Verknüpfen leerer Strings ("") vor und hinter den eigentlichen Inhalten? Warum setzt du die Werte für die Felder der Datenbank nicht in Anführungszeichen?
Desweiteren ist es nicht empfehlenswert, Daten vor dem Abspeichern bereits für die Ausgabe zu formatieren - genau das machst du hier, indem du nl2br() auf $\_POST['wunsch'] anwendest, damit bereitest du den Text nämlich für die Ausgabe in einem HTML Kontext vor. Allerdings kümmerst du dich überhaupt nicht um [Cross-Site Scripting](http://de.wikipedia.org/wiki/Cross-Site_Scripting), würde jemand HTML-Code eingeben, würdest du diesen später in der Datenbank haben mit dem von dir gewünschten <br />. Deshalb solltest du [htmlentities()](http://de2.php.net/htmlentities) bzw. [htmlspecialchars()](http://de2.php.net/htmlspecialchars) verwenden:
`$entschaerft = nl2br(htmlentities($_POST['wunsch']));`{:.language-php}
Und das schreibst du dann (nach weiterem Escapen gegen SQL-Injektionen, s.o.) in die Datenbank - das würde funktionieren. Wäre allerdings schlecht - was wäre, wenn du die Daten nun per Text E-Mail verschicken willst? Du hast in der Datenbank nur die Daten als HTML stehen! Bedenke: In einer Text E-Mail gibt es kein <br />, nur simplen Text ;-)
Aus diesem Grund solltest du Daten im Roh-Format in der Datenbank speichern (also kein nl2br(), kein htmlentities(), nur Escaping gegen SQL-Injektionen - aber das brauchst du sowieso IMMER!) und erst wenn du die Daten ausgibst, maskierst du sie entsprechend dem Kontext. Dass heißt: Wenn du sie im HTML ausgeben willst, nehme htmlentities() und falls gewünscht auch noch nl2br().
> ~~~php
if(sql_insert) {
> echo "Ihr Auftrag wurde erfolgreich gesendet.";
> }
Was willst du hier machen? Willst du wieder die Funktion sql_insert() aufrufen? Dann fehlen die Klammern hinter "sql_insert". Willst du die Rückgabe des Funktionsaufrufes von oben auswerten? Dann musst du die Rückgabe oben zwischenspeichern in eine Variable, welche du dann hier auswerten kannst.
So wie das hier ist dürfte das maximal eine Fehlermeldung von PHP geben: "Notice: Use of undefined constant sql_insert", wenn du diese nicht angezeigt bekommst, solltest du deine Einstellungen von PHP fürs Entwickeln anpassen (Stichwort error_reporting und display_errors).
<TD>GESCHLECHT</TD>
<TD><INPUT type="radio" name="geschlecht" value="mann" onchange="geschlechtm()">MANN | <INPUT type="radio" name="geschlecht" value="frau" onchange="geschlechtw()">FRAU</TD>
Auch wenn es grundsätzlich empfehlenswert ist, gerade bei Radio-Buttons solltest du auf jeden Fall [Label](http://de.selfhtml.org/html/formulare/strukturieren.htm#label) verwenden. Du erreichst damit einen besser strukturierten Quelltext und verhinderst Frustration bei Besuchern wie mir, welche es nicht leiden können, wenn man mit der Maus in den kleinen Kreis klicken muss und nicht (wie von Windows-Programmen und besseren Webseiten gewöhnt) auch einfach auf den Text daneben klicken kann, um den Radio-Button auszuwählen.
> ~~~html
<TD>VORNAME:</TD>
> <TD><INPUT type="text" size="25" name="vorname" onchange="vorname()"></TD>
Warum verwendest du kein Affenformular? Findest du nicht, dass es als Besucher äußerst nervend ist, wenn man alles noch mal neu eingeben muss, nur weil man beim Ausfüllen einen Fehler gemacht hat?
Wie du ein Affenformular in PHP bastelst, ist u.a. hier erklärt.
<TD><INPUT type="submit" value="SENDEN" name="senden" onMouseOver="senden()"/></TD>
Ich weiß ja nicht, was deine Javascript-Funktion senden() macht, aber gehe ich mal davon aus, dass sie hält, was sie verspricht, so würde dieses Formular abgesandt, sobald man mit der Maus über den Senden-Button fährt.
Was soll das? Versuchst du gezielt User zu verärgern? Du entfremdest hiermit ein Element, welches der Benutzer aus seinem täglichen Arbeiten mit dem PC sehr gut kennt: Einen Button. Jedem, der mit einem PC arbeitet, wird intuitiv bewusst sein, dass man mit einem Button etwas machen kann und zwar genau dann, wenn man draufklickt. Du aber reagierst schon auf das Überfahren des Buttons mit der Maus, wodurch du das allgemein bekannte Konzept zerstörst.
Wenn du irgendwelche Validierungen vornehmen willst, dann verwende onclick für den Submit-Button, oder onsubmit für das Formular.
Viele Grüße,
~ Dennis.
Hi Dennis,
ok das war viel information
Also ich erkäre kurz mein script:
Das php-script war und ist noch nicht fertig, weil ich gemerkt habe das mein Javasript nicht funktioniert. Die daten sollen alle in eine MySQL-Tabelle gespeichert werden, welche ich später im Admin-bereich abrufen kann, deswegen ist das oben fehlerhaft. sql_insert() ist eine Funktion, welche mir einfach nur die tipparbeit ersparen soll.
die htmlentities() und htmlspecialchars() werden natürl. noch eingebaut.
Ich hab zwar noch nicht draufgeklickt aber ich werde mir mal das affenformular anschauen.
der senden()-befehl soll das script nicht senden, sondern überprüfen ob alles ausgefüllt ist...naja egal, den werde ich eh löschen, weil dieser leicht umgänglich ist und evtl. auch nervig.
Also, vielen Dank für deine Tipps, ich werde gleich mal einige davon umsetzen
MFG
Abbadon
Hi Dennis,
Allerdings kümmerst du dich überhaupt nicht um Cross-Site Scripting, würde jemand HTML-Code eingeben, würdest du diesen später in der Datenbank haben mit dem von dir gewünschten <br />. Deshalb solltest du htmlentities() bzw. htmlspecialchars() verwenden:
$entschaerft = nl2br(htmlentities($_POST['wunsch']));
Und das schreibst du dann (nach weiterem Escapen gegen SQL-Injektionen, s.o.) in die Datenbank - das würde funktionieren.
Ich such schon die ganze Nacht nach einer möglichkeit, das zu tun was du hier vorschlägst,
hab schon recht viel gefunden aber kann es nicht auf mein Script anpassen, kannst du mir helfen?
<?php
$interpret = $_POST['interpret'];
$album = $_POST["album"];
$datum = $_POST["datum"];
$songtext = $_POST['songtext'];
$fehler = false;
$fehlertext = "Folgende Felder sind leer:<br />";
if(empty($interpret)){
$fehler = true;
$fehlertext .= "Interpret<br />";
}
if(empty($album)){
$fehler = true;
$fehlertext .= "Album<br />";
}
if(empty($datum)){
$fehler = true;
$fehlertext .= "Datum<br />";
}
if(empty($songtext)){
$fehler = true;
$fehlertext .= "Songtext<br />";
}
if($fehler == true) {
echo "<p>".$fehlertext."</p>";
}
else {
echo "<p>Das Formular wurde versendet.</p> ";
$eintrag = "INSERT INTO songtexte (interpret, album, datum, songtext)
VALUES ( '$interpret', '$album', '$datum', '$songtext')";
$eintragen = mysql_query($eintrag);
}
?>
Egal was ich mach, <> krieg ich einfach nicht maskiert.
Grüße,
Engin
GYRO
Hi Engin,
also wenn du das um z.B. songtext drumhaben willst würde ich das so schreiben:
$eintrag = "INSERT INTO songtexte (interpret, album, datum, songtext)
VALUES ( '$interpret', '$album', '$datum', '".nl2br(htmlentities(htmlspecialchars($songtext)))."')";
$eintragen = mysql_query($eintrag);
echo $begrüßung;
$eintrag = "INSERT INTO songtexte (interpret, album, datum, songtext)
VALUES ( '$interpret', '$album', '$datum', '".nl2br(htmlentities(htmlspecialchars($songtext)))."')";
Nein, so nicht! Du hast hier ein SQL-Statement als Kontext, kein HTML. Du behandelst den $songtext nach allen unmöglichen Kriterien, nur nicht nach den einzig wichtigen. Stattdessen kommen durch deine Behandlung verunstaltete Daten in der Datenbank an, die nicht mehr richtig durchsuchbar sind. Für den MySQL-Kontext ist die Funktion mysql_real_escape_string() zuständig. Das gilt auch für die anderen Werte, die in eine SQL-Query einsetzt werden sollen.
htmlentities() und htmlspecialchars() sind außerdem zwei Funktionen, die sich gegenseitig ausschließen, weil sie beide die Zeichen <>&" behandeln. Das ergibt maskierte Maskierungen. Ansonsten siehe dort: </archiv/2008/1/t164688/#m1073706>
echo "$verabschiedung $name";
sry für doppelpost aber mir fällt da noch was auf:
ich würde bei deiner Abfrage nicht empty() sondern trim() benutzen
(z.B. if(trim($_POST['album'] != "") { }
), denn dann schliest er auch leerzeichen aus, was er bei empty() nicht macht
Hi,
sry für doppelpost aber mir fällt da noch was auf:
ich würde bei deiner Abfrage nicht empty() sondern trim() benutzen
(z.B.if(trim($_POST['album'] != "") { }
), denn dann schliest er auch leerzeichen aus, was er bei empty() nicht macht
trim wirft einen Fehler, wenn der entsprechende Wert gar nicht existent ist.
empty weiss damit umzugehen.
MfG ChrisB
trim wirft einen Fehler, wenn der entsprechende Wert gar nicht existent ist.
Hast du den befehl direkt kopiert? den ich sehe gerade ich hab einen fehler drin, es fehlt näml. eine ")"
if(trim($_POST['album']) != "") { echo "Album fehlt"; }
Mit dieser abfrage löscht er alle leerzeichen vor und hinter dem string: z.B.:
$string = " a ";
echo trim($string); //er schreibt dann nur "a"
wenn du also einen string mit leerzeichen sendest, löscht er diese vor und hinter dem text. Ist kein text vorhanden löscht er alle und somit schließt du aus, das der Besucher einen leeren string sendet. Bei empty aber kannst du ein leerzeichen z.B. als string absenden.
Hallo
wenn du also einen string mit leerzeichen sendest, löscht er [trim] diese vor und hinter dem text. Ist kein text vorhanden löscht er alle und somit schließt du aus, das der Besucher einen leeren string sendet. Bei empty aber kannst du ein leerzeichen z.B. als string absenden.
Der Besucher hat in diesem Moment schon gesendet. Das ist alles schon vorbei.
Somit ist es auch unmöglich, mit empty()
zu verhindern, dass der Besucher ein Leerzeichen in einem Formularfeld abschickt. Im übrigen wäre das Feld somit _nicht_ leer und empty()
wäre false
.
Tschö, Auge
echo $begrüßung;
Und das schreibst du dann (nach weiterem Escapen gegen SQL-Injektionen, s.o.) in die Datenbank - das würde funktionieren.
Ich such schon die ganze Nacht nach einer möglichkeit, das zu tun was du hier vorschlägst,
hab schon recht viel gefunden aber kann es nicht auf mein Script anpassen, kannst du mir helfen?
Du solltest öfter die anderen Probleme hier im Forum lesen und die Antworten darauf. Solche Probleme werden hier regelmäßig behandelt. Der Grundsatz lautet: Wann immer Werte in einen bestimmten Kontext gebracht werden, so sind diese für diesen (und nur für diesen) Kontext zu behandeln. PHP stellt dafür bereits Funktionen zur Verfügung: Fügst du Werte in ein MySQL-Statement ein, ist es mysql_real_escape_string(). Fügst du Werte in HTML ein, ist es htmlspecialchars() (htmlentities() vs. htmlspecialchars()). Fügst du Werte in eine URL ein, ist es für den Querystring urlencode(), ansonsten rawurlencode(). Fügt man eine bereits behandelte URL in einen HTML-Kontext ein, so ist diese auch noch mal gemäß HTML-Kontext zu behandeln. Fügt man Werte in einen Javascript-Code ein ... usw. usf.
Egal was ich mach, <> krieg ich einfach nicht maskiert.
Um welche <> geht es denn? Diese beiden Zeichen sind im MySQL-Kontext völlig harmlos. Dafür müssen sie nicht behandelt werden. Sie müssen erst dann behandelt werden, wenn sie in einen Kontext eingefügt werden sollen, der sie als Sonderzeichen ansieht, HTML beispielsweise.
echo "$verabschiedung $name";
Hi dedlfix,
Du solltest öfter die anderen Probleme hier im Forum lesen und die Antworten darauf. Solche Probleme werden hier regelmäßig behandelt.
Fügst du Werte in ein MySQL-Statement ein, ist es mysql_real_escape_string(). Fügst du Werte in HTML ein, ist es htmlspecialchars() (htmlentities() vs. htmlspecialchars()).
Ich hab mich in den letzten 2 Tagen irgendwie in alles reingelesen, meine schwierigkeiten
beruhen nur darauf, das ich nicht weiss, wie ich Scripte miteinander kombinier, und das was ich explizit suche finde ich einfach nicht.
Egal was ich mach, <> krieg ich einfach nicht maskiert.
Um welche <> geht es denn? Diese beiden Zeichen sind im MySQL-Kontext völlig harmlos. Dafür müssen sie nicht behandelt werden.
Du verwirrst mich grad ein wenig. :) Muss ich nicht eingaben Prüfen, bevor
ich diese in meine DB schreibe? Ich hab mir ne testseite angefertigt, wenn ich darüber z.b. <a href=a>a</a> in die Datenbank schreibe und
das gespeicherte aus der Datenbank abrufe, in meinem Browser steht
es im html Dokument so wie oben <a href=a>a</a>.
Du verstehst ja sicherlich, was das Ziel des Scriptes ist, wie soll ich das ganze umsetzen?
Ich hab gestern Nacht auch mit sachen wie
strip_tags($songtext);
str_replace('"', '*', $songtext);
str_replace("\r", "", $songtext);
str_replace("\n", "", $songtext);
stripcslashes($songtext);
trim($songtext);
" " . $songtext;
rawurlencode ($songtext);
Nur die Ausgabe war nicht wie gewünscht, da kamen dann sachen wie %3irgendwas und auch
die \n hab ich nicht als <br> ausgegeben gekriegt, die kamen dann auch irgendwie mit %3br%3.
Sie müssen erst dann behandelt werden, wenn sie in einen Kontext eingefügt werden sollen, der sie als Sonderzeichen ansieht, HTML beispielsweise.
Zurzeit lese ich die Daten aus der DAtenbank mit diesem Script aus
<?php
$sql = 'SELECT * FROM `songtexte` LIMIT 0, 30 ';
$ergebnis = mysql_query($sql);
while($row = mysql_fetch_object($ergebnis))
{
echo "$row->songtext <br />";
}
hier muss ich dann wohl htmlspecialchars() nutzen, seh ich das richtig?
Grüße,
Engin
GYRO
echo $begrüßung;
Egal was ich mach, <> krieg ich einfach nicht maskiert.
Um welche <> geht es denn? Diese beiden Zeichen sind im MySQL-Kontext völlig harmlos. Dafür müssen sie nicht behandelt werden.
Du verwirrst mich grad ein wenig. :) Muss ich nicht eingaben Prüfen, bevor ich diese in meine DB schreibe?
Betrachte bitte jeden Kontext getrennt für sich allein. Es ist uninteressant, welche Kontexte später mal eine Rolle spielen werden.
Wenn du bestimmte _Inhalte_ nicht speichern möchtest, kannst du diese natürlich entfernen. Aber mach das nur, wenn der Inhalt nicht zum Thema der Anwendung passt. Besonderheiten irgendeines (späteren) Ausgabemediums sind kein Kriterium für das Bearbeiten der Inhalte.
Ich hab mir ne testseite angefertigt, wenn ich darüber z.b. <a href=a>a</a> in die Datenbank schreibe und das gespeicherte aus der Datenbank abrufe, in meinem Browser steht es im html Dokument so wie oben <a href=a>a</a>.
Möchtest du dies - für die Ausgabe betrachtet - als Inhalt gewertet wissen oder als HTML-Code? Wenn es anzuzeigender Inhalt ist, dann bearbeite ihn HTML-gerecht, im Augenblick der Übergabe an das Ausgabemedium. Sprich: echo htmlspecialchars($inhalt);
Du verstehst ja sicherlich, was das Ziel des Scriptes ist, wie soll ich das ganze umsetzen?
Ich hab gestern Nacht auch mit sachen wie
[wenig sinnvolle Behandlung]
Nur die Ausgabe war nicht wie gewünscht, da kamen dann sachen wie %3irgendwas und auch
die \n hab ich nicht als <br> ausgegeben gekriegt, die kamen dann auch irgendwie mit %3br%3.
Mit Kanonen auf Spatzen zu schießen erzeugt nun mal große Löcher in der Landschaft. Mitunter fliegt der Spatz auch noch weg bevor die Kugel trifft.
Zurzeit lese ich die Daten aus der DAtenbank mit diesem Script aus
echo "$row->songtext <br />";
hier muss ich dann wohl htmlspecialchars() nutzen, seh ich das richtig?
Ja, und nur das.
echo "$verabschiedung $name";
Hi dedlfix,
Betrachte bitte jeden Kontext getrennt für sich allein. Es ist uninteressant, welche Kontexte später mal eine Rolle spielen werden.
Ok, das habe ich begriffen, ich hab die ganze Zeit überlegt, wie ich das später auszugebende bereits bei der Eingabe
Sauber (für die HTML Ausgabe) in die Datenbank kriege.
Das war wohl der falsche Ansatz.
Wenn es anzuzeigender Inhalt ist, dann bearbeite ihn HTML-gerecht, im Augenblick der Übergabe an das Ausgabemedium. Sprich: echo htmlspecialchars($inhalt);
Das kommt dann als nächster schritt an die Reihe.
Ich hab deinen Vorschlag vom ersten Post mit mysql_real_escape versucht umzusetzen,
hab da auch was gefunden, nur irgendwie scheint das auch nicht richtig zu sein.
Wenn in der Textarea ein \ benutzt wird schickt er die Informationen manchmal ab ab und entfernt das , teilweise wird es aber auch nicht abgeschickt.
Auch z.b. werden ' manchmal mit übergeben, manchmal nicht.
Wenn ich - tz'w - bekomme ich als ausgabe - tz'w - und wenn ich \n schreibe
bekomme ich im Quelltext einen Zeilen umbruch. Ist das richtig so?
Hier mal mein Katastrophales Script, hoffe ich nerv dich nicht allzu sehr.
// DB Connect
$link = mysql_connect('***', '***', '***');
// nach den überprüfungen, ob Felder leer sind
else {
echo "<p>Das Formular wurde einwandfrei ausgefüllt.</p> ";
if (isset($_POST['interpret'])
&& isset($_POST['album'])
&& isset($_POST['songtext'])) {
if(!is_resource($link)) {
echo "Verbindung zum Server fehlgeschlagen\n";
} else {
if(get_magic_quotes_gpc()) {
$interpret = stripslashes($_POST['interpret']);
$album = stripslashes($_POST['album']);
$songtext = stripslashes($_POST['songtext']);
} else {
$interpret = $_POST['interpret'];
$album = $_POST['album'];
$songtext = $_POST['songtext'];
}
$eintrag = sprintf ("INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('$interpret', '$album', '$datum', '$songtext')",
mysql_real_escape_string($interpret),
mysql_real_escape_string($album),
mysql_real_escape_string($songtext),
$_POST['user_id']);
$eintragen = mysql_query($eintrag);
if (mysql_affected_rows($eintrag) > 0) {
echo "Produkt eingefuegt\n";
}
}
}
}
Grüße,
Engin
GYRO
Hi Engin,
Ok, das habe ich begriffen, ich hab die ganze Zeit überlegt, wie ich das später auszugebende bereits bei der Eingabe
Sauber (für die HTML Ausgabe) in die Datenbank kriege.
Das war wohl der falsche Ansatz.
Ich verstehe deine Denkweise ;-) Du willst die Datenbank sauber halten, bedenke aber bitte, dass die Datenbank kein Datenträger bei dir zu Hause in einem Safe ist, wo niemand drankommt. Du musst grundsätzlich davon ausgehen, dass theoretisch jemand deine Datenbank cracken könnte und dir "böse" Daten in die Datenbank schreiben könnte.
Aus diesem Grund sollte dein Ausgabe-Programm mit _jeglichem_ Inhalt aus der Datenbank rechnen und ihn z.B. für die HTML-Ausgabe stets korrekt kodieren, die Funktionen htmlentities() und htmlspecialcahrs() kennst du nun ja.
if(get_magic_quotes_gpc()) {
$interpret = stripslashes($_POST['interpret']);
$album = stripslashes($_POST['album']);
$songtext = stripslashes($_POST['songtext']);
} else {
$interpret = $_POST['interpret'];
$album = $_POST['album'];
$songtext = $_POST['songtext'];
}
Gut, du hast selber schon festgestellt, dass PHP ein sehr nervendes Feature names magic_quotes besitzt - zum Glück wird dieses ab PHP 6 nicht mehr existieren, deshalb ist es gut, wenn du es hier direkt richtig machst: Falls magic_quotes aktiviert war, mache es mit stripslashes() rückgängig.
$eintrag = sprintf ("INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('$interpret', '$album', '$datum', '$songtext')",
mysql_real_escape_string($interpret),
mysql_real_escape_string($album),
mysql_real_escape_string($songtext),
$_POST['user_id']);
Mache dir bitte bewusst, was hier passiert, du hast folgenden String notiert:
"INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('$interpret', '$album', '$datum', '$songtext')"
Das ist ein double-quoted String, also zwischen " eingeschlossen. In einem solchen String werden Variablen ersetzt, PHP macht daraus also:
"INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('Max Mustermann', 'Musteralbum', '2008-01-01', 'Trala la la la')"
Und erst _dieser String_ wird an die Funktion sprintf() übergeben! Was soll denn sprintf() deiner Meinung da noch machen? Da steht doch schon alles drin ;-)
Sicherlich ist sprintf() nicht gerade die einfachste Funktion zum Nutzen, vielleicht solltest du erst mal die Anfänger-Methode bevorzugen:
~~~php
$sql = "INSERT INTO songtexte (
interpret,
album,
datum,
songtext
)
VALUES (
'" . mysql_real_escape_string($interpret) . "',
'" . mysql_real_escape_string($album) . "',
'" . mysql_real_escape_string($datum) . "',
'" . mysql_real_escape_string($songtext) . "'
)";
$result = mysql_query($sql) OR die(mysql_error());
Ich habe hier auch noch eine Auswertung der Rückgabe von mysql\_query() eingebaut, im Fehlerfall gibt das Script die Fehlermeldung von mysql\_error() aus und bricht ab. Im Produktiveinsatz ist das nicht empfehlenswert, zum Debuggen und Entwickeln aber sehr hilfreich.
Gut, das war jetzt die simple Methode, nun wie es mit sprintf() funktioniert:
~~~php
$sql = "INSERT INTO songtexte (
interpret,
album,
datum,
songtext
)
VALUES (
'%s',
'%s',
'%s',
'%s'
)";
$sql = sprintf(
$sql,
$interpret,
$album,
$datum,
$songtext
);
$result = mysql_query($sql) OR die(mysql_error());
Das ist jetzt sehr lang und ausführlich geschrieben, natürlich geht es auch kürzer:
~~~php
$sql = sprintf(
"INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('%s', '%s', '%s', '%s')",
$interpret,
$album,
$datum,
$songtext
);
$result = mysql_query($sql) OR die(mysql_error());
Wie man das nun genau notiert, ist letztendlich egal und eine Frage des Programmierstils. Ich persöhnlich bevorzuge es, den SQL-Query über mehrere Zeilen zu notieren, da dies einerseits übersichtlicher ist meiner Meinung nach und andererseits man Fehler im Query leichter findet, da MySQL normalerweise die Zeilennummer sagt, in der der Fehler liegt - notiert man den gesamten Query in einer Zeile, so hilft es einem nicht weiter, wenn man weiß, dass der Fehler in Zeile 1 liegt ;-)
Viele Grüße,
~ Dennis.
--
Mein [SelfCode](http://community.de.selfhtml.org/fanprojekte/selfcode.htm): [ie:{ fl:( br:> va:) ls:\[ fo:) rl:( n4:# ss:) de:\] js:| ch:{ sh:| mo:} zu:|](http://www.peter.in-berlin.de/projekte/selfcode/?code=ie%3A%7B+fl%3A%28+br%3A%3E+va%3A%29+ls%3A%5B+fo%3A%29+rl%3A%28+n4%3A%23+ss%3A%29+de%3A%5D+js%3A%7C+ch%3A%7B+sh%3A%7C+mo%3A%7D+zu%3A%7C)
Hi,
~~~php
$sql = sprintf(
"INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('%s', '%s', '%s', '%s')",
$interpret,
$album,
$datum,
$songtext
);
$result = mysql_query($sql) OR die(mysql_error());
Autsch, jetzt wollte ich ein schönes Beispiel schreiben und habe selber vergessen, mysql\_real\_escape\_string() da hinein zu schreiben ;-) Dies hier (und genauso bei meinem ersten sprintf()-Beispiel) muss natürlich lauten:
~~~php
$sql = sprintf(
"INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('%s', '%s', '%s', '%s')",
mysql_real_escape_string($interpret),
mysql_real_escape_string($album),
mysql_real_escape_string($datum),
mysql_real_escape_string($songtext)
);
$result = mysql_query($sql) OR die(mysql_error());
Viele Grüße,
~ Dennis.
Hi Dennis,
Du musst grundsätzlich davon ausgehen, dass theoretisch jemand deine Datenbank cracken könnte und dir "böse" Daten in die Datenbank schreiben könnte.
Das ist ja auch der einzige Grund, warum ich schon seit tagen an der ersten Hürde hängen bleib. :)
Ich wäre laut meiner Planung eigentlich schon bei der Ausgabe des HTML Codes
aber die mysql Geschichte lässt nicht locker.
Falls magic_quotes aktiviert war, mache es mit stripslashes() rückgängig.
ja, sind bei mir Aktiv, auf 1.
Das ist ein double-quoted String, also zwischen " eingeschlossen. In einem solchen String werden Variablen ersetzt, PHP macht daraus also:
"INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('Max Mustermann', 'Musteralbum', '2008-01-01', 'Trala la la la')"
Und erst _dieser String_ wird an die Funktion sprintf() übergeben!
Was soll denn sprintf() deiner Meinung da noch machen? Da steht doch schon alles drin ;-)
Keine Ahnung. :)) Ich weiss doch seit Tagen selber nicht, was ich hier mache.
Du musst dir mal meine Logs ansehen, wieviel _POST es in den letzten Tagen auf dem Server gab. :)
~~~php
$sql = sprintf(
"INSERT INTO songtexte (interpret, album, datum, songtext) VALUES ('%s', '%s', '%s', '%s')",
mysql_real_escape_string($interpret),
mysql_real_escape_string($album),
mysql_real_escape_string($datum),
mysql_real_escape_string($songtext)
);
$result = mysql_query($sql) OR die(mysql_error());
Vielen Dank für deine beispiele, aber irgendwo läuft bei mir was gewaltig schief. Sämtliche Eingaben werden
in der DB unverändert gespeichert, ob´s \ oder ', einfach alles.
Ich hab jetzt auch keine Zeit mehr weiter zu testen, werd mich Heute Abend wieder dran setzen.
Wenn du lust und Zeit hast könntest du ja mal drüber schauen,
<http://nimmet.de/beispiele/dbtest.txt>, aber nicht erschrecken,
das ganze ist irgendwie nur noch ein haufen Chaos, wollte das in Ordnung bringen,
wenn ich es denn endlich zum laufen kriege.
Grüße,
Engin
GYRO
--
["ich bin ein Insekt, ich bin ein Insekt"](http://nimmet.de/nimmet-dateien/banjo.shtml)
![](http://nimmet.de/nimmet-bilder/valigator.gif)[Der Valligator](http://old.atomic-eggs.com/old_forum/messages/237.html#a1)
["I would like to buy a hamburger"](http://www.youtube.com/watch?v=x8S7x_z1w1s)
echo $begrüßung;
Vielen Dank für deine beispiele, aber irgendwo läuft bei mir was gewaltig schief. Sämtliche Eingaben werden
in der DB unverändert gespeichert, ob´s \ oder ', einfach alles.
Genau das ist das Ziel. mysql_real_escape_string() versieht diese Werte nur mit einer Transportsicherung. Wenn du ein Gerät zu Hause stehen hast, ist keine Transportsicherung mehr nötig. Im Gegenteil, sie ist für den bestimmungsgemäßen Gebrauch eher hinderlich.
Ein SQL-Statement (und HTML ebenso) mischt Anweisungsteile mit Daten, um sie gemeinsam zu übertragen. Um zu unterscheiden, dass nun ein Teil Daten kommt, muss er gekennzeichnet werden. Er wird in "" oder '' eingerahmt. Man nennt das Quotieren. Innerhalb dieses quotierten Teils muss man nun wiederum zwischen einem Quotierungsende und einem " oder ' als Datenbestandteil unterscheiden. Deswegen notiert man es als Datenbestandteil in der Form " bzw. ' und hat damit nun auch noch den \ als besonders zu kennzeichnen, leitet dieser doch nun eine Maskierung ein. Hinzu kommen noch ein paar Sonderzeichen, die ebenfalls mit einem vorangehenden \ notiert werden, wie beispielsweise der Zeilenumbruch in Form eines \n.
Für HTML ist das ähnlich, hier sind die Zeichen < und > zu beachten, und weil die Maskierungen mit einem & anfangen (< und >), auch dieses (&). Innerhalb von Attributwerten kommt noch " bzw. ' hinzu (" und 9).
URLs sind ein weiteres Beispiel. Hier werden ebenfalls Zeichen mit besonderer Bedeutung, die in Werten vorkommen, umgeschrieben.
Diese Transportsicherungen werden vom Empfänger selbständig entfernt. Er arbeitet nur noch mit den Roh-Daten. Gegebenenfalls sind auch beim "Rücktransport" Sicherungsmaßnamen zu ergreifen. Doch für Datenbanken ist das nicht nötig. Die Daten werden beim Auslesen nicht mehr in einen Anweisungstext eingebunden sondern direkt geliefert. Beim Abfragen der Datenbankwerte muss man also keine Demaskierung vornehmen.
echo "$verabschiedung $name";
Hi dedlfix,
Vielen Dank für deine beispiele, aber irgendwo läuft bei mir was gewaltig schief. Sämtliche Eingaben werden
in der DB unverändert gespeichert, ob´s \ oder ', einfach alles.Genau das ist das Ziel. mysql_real_escape_string() versieht diese Werte nur mit einer Transportsicherung.
Also kann ich mich jetzt auf die Ausgabe konzentrieren?
Woher weiss ich denn nun, ob bei mir alles richtig ist?
Grüße,
Engin
GYRO
echo $begrüßung;
Woher weiss ich denn nun, ob bei mir alles richtig ist?
Indem du sowohl mit ein paar "normalen" Nutzdaten und auch mit ein paar "gefährlichen" Daten deine Anwendung zu malträtieren versuchst. Z.B. wenn eine Zahl gefordert ist, gib stattdessen Buchstaben oder anderen Blödsinn ein. Gib sie in Hex-Notation oder in Exponentialdarstellung ein. Lies in der Dokumentation der beteiligten Systeme nach, welche Zeichen eine Sonderstellung einnehmen und füttere auch damit deine Anwendung. Sie muss das alles ohne Schaden überstehen. Versuche dich in die Gegenseite hineinzudenken. Wie muss man vorgehen, um eine Anwendung zu kompromittieren? Informiere dich zu den Begriffen, die nicht nur hier überall rumschwirren, z.B. SQL-Injection und XSS. Versuche so etwas nachzustellen, damit du lernst, wie diese Angriffe funktionieren und wie diese Sicherheitslücken auszunutzen sind. Lerne auch, wie man seine Anwendungen dagegen immun programmiert. Und dann beobachte die Szene mit offenen Augen. Es gibt immer wieder neue Dinge zu entdecken.
echo "$verabschiedung $name";
Hi dedlfix,
z.B. SQL-Injection und XSS. Versuche so etwas nachzustellen, damit du lernst, wie diese Angriffe funktionieren und wie diese Sicherheitslücken auszunutzen sind. Lerne auch, wie man seine Anwendungen dagegen immun programmiert. Und dann beobachte die Szene mit offenen Augen.
Danke für den Tip, werde mich gleich mal auf die suche machen, wollte dir
grade weiter eigentlich noch ne frage stellen, mach ich jetzt mal hier unten,
if(get_magic_quotes_gpc()) {
Es ist besser, diese Magic-Quotes-Gegenmaßnahme einmalig am Scriptanfang auf die kompletten Eingabedaten-Arrays auszuführen. Am besten mit dem unter http://www.php.net/manual/en/security.magicquotes.disabling.php aufgeführten Beispiel.
Ich hab die Magic-Quotes jetzt komplett über eine php.ini deaktiviert, genügt es mit
mysql_real_escape_string zu arbeiten, oder soll ich das andere bsp. aus der verlinkten Seite nehmen?
Also
Magic-Quotes-Gegenmaßnahme einmalig am Scriptanfang auf die kompletten Eingabedaten-Arrays auszuführen
Grüße,
Engin
GYRO
echo $begrüßung;
Ich hab die Magic-Quotes jetzt komplett über eine php.ini deaktiviert, genügt es mit
mysql_real_escape_string zu arbeiten, oder soll ich das andere bsp. aus der verlinkten Seite nehmen?
Wenn du die Magic Quotes global deaktiviert hast und sichergehen kannst, dass sie nicht irgendwer wieder aktiviert, dann brauchst du keine weiteren Gegenmaßnahmen mehr zu verwenden. (Die kontextgerechte Maskierung mittels mysql_real_escape_string() muss natürlich bleiben.)
echo "$verabschiedung $name";
Hi dedlfix,
Wenn du die Magic Quotes global deaktiviert hast und sichergehen kannst, dass sie nicht irgendwer wieder aktiviert, dann brauchst du keine weiteren Gegenmaßnahmen mehr zu verwenden.
Ich habe es über eine php.ini in dem Verzeichnis, von dem ich das eingabe Formular aufrufe, gelöst.
Ich glaub nicht, das mein Webhoster das dort entfernen würde, 1und1, reicht
das, wenn ich es nur über das Verzeichnis, in dem das Formular liegt regel oder muss es Global geschehen?
(Die kontextgerechte Maskierung mittels mysql_real_escape_string() muss natürlich bleiben.)
Also wie aus dem bsp. von Dennis?
Grüße,
Engin
GYRO
echo $begrüßung;
Ich habe es über eine php.ini in dem Verzeichnis, von dem ich das eingabe Formular aufrufe, gelöst.
Ich glaub nicht, das mein Webhoster das dort entfernen würde, 1und1, reicht
das, wenn ich es nur über das Verzeichnis, in dem das Formular liegt regel oder muss es Global geschehen?
Bei 1&1 ist es so, dass in dem Verzeichnis, aus dem ein PHP-Script gestartet wird, eine dort liegende php.ini die globale 1&1-php.ini komplett außer Kraft setzt. Es ist empfehlenswert, vor dem Anlegen einer eigenen php.ini via phpinfo() die von 1&1 gesetzten Werte auszulesen und dann zu schauen, welche sich nach dem Anlegen der eigenen php.ini geändert haben - sprich: wieder auf PHP-Default-Werten statt auf 1&1-Default-Werten stehen - und diese ebenfalls in der eigenen php.ini nachzuziehen (inklusive der Konfigurationswerte der (von einem selbst verwendeten) Extensions). Noch besser ist es, sich alle Werte anzuschauen und selbst zu entscheiden, wie er gesetzt werden soll. Das setzt natürlich einiges an Erfahrung bzw. Recherche nach dem Für und Wider der verschiedenen Einstellmöglichkeiten voraus.
Du musst in jedem Verzeichnis, in dem ein Script gestartet werden soll, so eine php.ini anlegen, alternativ einen Symlink auf eine php.ini eines anderen Verzeichnisses. Es gilt jeweils nur die php.ini des Script-Startverzeichnisses. Include-Dateien aus anderen Verzeichnisses werden ja im Kontext des Hauptscripts ausgeführt. Es ist also nicht so, dass für jede Include-Datei eine andere php.ini gilt (es sei denn natürlich, man ruft sie als eigenständiges Script auf). Für reine Include-Verzeichnisse ist es sowieso empfehlenswert, sie außerhalb des DocumentRoot abzulegen.
/kunden/engin <- nennen wir es mal KundenRoot.
/kunden/engin/nimmet <- DocumentRoot der Domain nimmet.example.org
/kunden/engin/gyro <- DocumentRoot der Domain gyro.example.com
/kunden/engin/includes <- ohne Domain. Inhalte übers Web nicht direkt erreichbar.
Das Script /kunden/engin/nimmet/index.php, aufgerufen von nimmet.example.org/index.php inkludiert seine Dateien dann via include '../includes/datei.ext';
Wenn man gerade Kunde geworden ist, zeigen die dabei miterworbenen Domains (inklusive der s_zahlenhaufen.kundenserver.de) alle ins KundenRoot, so dass die gesamte Unterverzeichnisstruktur darüber auslesbar ist. Das sollte man erstmal zugunsten einer Struktur, ähnlich der oben erwähnten, ändern.
echo "$verabschiedung $name";
Hi dedlfix,
Bei 1&1 ist es so, dass in dem Verzeichnis, aus dem ein PHP-Script gestartet wird, eine dort liegende php.ini die globale 1&1-php.ini komplett außer Kraft setzt. Es ist empfehlenswert, vor dem Anlegen einer eigenen php.ini via phpinfo() die von 1&1 gesetzten Werte auszulesen und dann zu schauen, welche sich nach dem Anlegen der eigenen php.ini geändert haben -
Danke für den Hinweis, da haben sich tatsächlich einige Werte geändert,
das hätte ich garnicht gemerkt.
browscap /usr/local/lib/browscap.ini standard
browscap no value meine .ini
error_reporting 2037 standard
error_reporting no value meine .ini
magic_quotes_gpc On Standard
magic_quotes_gpc Off meine .ini
max_execution_time 50000 Standard
max_execution_time 30 meine .ini
memory_limit 40M Standard
memory_limit 8M meine .ini
upload_max_filesize 20M Standard
upload_max_filesize 2M meine .ini
url_rewriter.tags
a=href,area=href,frame=src,form=fakeentry,fieldset= standard
url_rewriter.tags
a=href,area=href,frame=src,form=,fieldset= meine .ini
REDIRECT_UNIQUE_ID ************** geändert
UNIQUE_ID ************** geändert
Werd mal recherchieren, was davon ich so haben möchte und was besser nicht.
Du musst in jedem Verzeichnis, in dem ein Script gestartet werden soll, so eine php.ini anlegen, alternativ einen Symlink auf eine php.ini eines anderen Verzeichnisses. Es gilt jeweils nur die php.ini des Script-Startverzeichnisses.
Die User eingaben wollte ich eh nur aus diesem einen Verzeichnis steuern,
das Verzeichnis werde ich noch mit einem Login versehen.
Das was ich vorhab ist ja eh keine so grosse Sache, lesen sollen alle User, Texte hinzufügen nur registrierte.
/kunden/engin/includes <- ohne Domain. Inhalte übers Web nicht direkt erreichbar.
Wie mach ich denn sowas bzw. was ist das Stichwort? Also das es nicht übers Web erreichbar ist,
höre ich zum ersten mal.
Grüße,
Engin
GYRO
echo $begrüßung;
REDIRECT_UNIQUE_ID ************** geändert
UNIQUE_ID ************** geändert
Das sind keine php.ini-Werte sondern die Inhalte von $_SERVER oder $_ENV. Die Werte aus dem Kasten dienen dir zur Information über bestimmte Server- oder Requestgegebenheiten. Die ändern sich, manche nie, manche bei jedem Request.
/kunden/engin/includes <- ohne Domain. Inhalte übers Web nicht direkt erreichbar.
Wie mach ich denn sowas bzw. was ist das Stichwort? Also das es nicht übers Web erreichbar ist, höre ich zum ersten mal.
Du musst das in Zusammenhang mit den anderen Zeilen sehen.
/kunden/engin <- nennen wir es mal KundenRoot.
/kunden/engin/nimmet <- DocumentRoot der Domain nimmet.example.org
/kunden/engin/gyro <- DocumentRoot der Domain gyro.example.com
/kunden/engin/includes <- ohne Domain. Inhalte übers Web nicht direkt erreichbar.
Den beiden Verzeichnissen nimmet und gyro ist jeweils eine Domain zugeordnet. Der Inhalt und dessen Unterverzeichnisse sind über das Web über die jeweilige Domain ansprechbar. Dem engin-Verzeichnis darf keine zugeordnet sein, auch nicht die Default-Domain, die 1&1 zu jedem Paket dazu gibt. Das kann man alles über die Domainverwaltung konfigurieren. Das include legst du einfach außerhalb der Domainen-Verzeichnisse an, und lässt keine Domain draufzeigen.
echo "$verabschiedung $name";
Hi dedlfix,
/kunden/engin <- nennen wir es mal KundenRoot.
/kunden/engin/nimmet <- DocumentRoot der Domain nimmet.example.org
/kunden/engin/gyro <- DocumentRoot der Domain gyro.example.com
/kunden/engin/includes <- ohne Domain. Inhalte übers Web nicht direkt erreichbar.
Den beiden Verzeichnissen nimmet und gyro ist jeweils eine Domain zugeordnet. Der Inhalt und dessen Unterverzeichnisse sind über das Web über die jeweilige Domain ansprechbar. Dem engin-Verzeichnis darf keine zugeordnet sein, auch nicht die Default-Domain, die 1&1 zu jedem Paket dazu gibt. Das kann man alles über die Domainverwaltung konfigurieren.
Mich bringen derzeit die Zeilen
nimmet.example.org und gyro.example.com
ein wenig durcheinander, ich muss mir mal die Domainverwaltung ansehen,
meinst du vielleicht subdomains? Also in der art http://engin.nimmet.de/ ? Das wäre kein problem, das geht fix.
Grüße,
Engin
GYRO
echo $begrüßung;
Mich bringen derzeit die Zeilen
nimmet.example.org und gyro.example.com
ein wenig durcheinander, ich muss mir mal die Domainverwaltung ansehen,
meinst du vielleicht subdomains? Also in der art http://engin.nimmet.de/ ? Das wäre kein problem, das geht fix.
Das sind nur beispielhafte Namen gewesen. Das Szenario gilt für jede beliebige Domain, egal ob es eine Subdomain oder "normale" Domain ist.
echo "$verabschiedung $name";
Hi dedlfix,
Das sind nur beispielhafte Namen gewesen. Das Szenario gilt für jede beliebige Domain, egal ob es eine Subdomain oder "normale" Domain ist.
Erstmal Danke für deine bisher aufgebrachte Geduld und Hilfe. :)
Ich war jetzt mal auf meiner Domain verwaltung, das einzige was ich finden
konnte war, geschützte Verzeichnisse anzulegen, aber nicht erreichbare Domains gibt es da irgendwie nicht.
Mal ne frage, wird dir diese Seite ohne Authentifizierung angezeigt?
Die Inhalte werden aus dem geschützten Verzeichnis herangezogen, meintest du sowas?
Ich hab Angst, das wenn jetzt irgendwer versucht, eine Seite aufzurufen, die
include Dateien aus einem geschützten Verzeichnis heranzieht sich Authentifizieren muss.
Wenn nicht könnte ich meine inc Verzeichnisse ja schnell absichern.
Grüße,
Engin
GYRO
echo $begrüßung;
Ich war jetzt mal auf meiner Domain verwaltung, das einzige was ich finden
konnte war, geschützte Verzeichnisse anzulegen, aber nicht erreichbare Domains gibt es da irgendwie nicht.
Im Kapitel Domain sind alle deine vorhandenen aufgeführt. Unter "Verwendungsart" siehst du, wohin sie zeigen. Und über den Menüpunkt "Verwendungsart bearbeiten" kann man das Documentroot einstellen.
Mal ne frage, wird dir diese Seite ohne Authentifizierung angezeigt?
Die Seite schon, die Linkziele nicht.
Die Inhalte werden aus dem geschützten Verzeichnis herangezogen, meintest du sowas?
Es ist über Web erreichbar, weswegen du dessen Inhalt auch mit einem Zugriffsschutz versehen musstest. Nimm den (aus Versehen) weg und man kann die Dateien erreichen. Dateien außerhalb des Documentroot benötigen keine extra Sicherungsmaßnahme, weil es keine URL gibt, um sie abzufragen (wenn man sich nicht irgendeinen Mechanismus selbst baut).
Ich hab Angst, das wenn jetzt irgendwer versucht, eine Seite aufzurufen, die
include Dateien aus einem geschützten Verzeichnis heranzieht sich Authentifizieren muss.
Das was deine PHP-Scripte im Dateisystem anstellen hat mit dem Webserver, und dem worauf der zugreifen darf, nicht viel gemeinsam. Grundsätzlich kann PHP sämtliche Verzeichnisse erreichen[*], und deren Inhalt in die angeforderte Ressource einbinden. Der Webserver kann aber nur die Dokumente unterhalb des Documentroot ausliefern.
[*] Restriktionen gibt es nur durch Zugriffsrechte und durch PHP-Konfigurationen wie SafeMode und open_basedir.
echo "$verabschiedung $name";
Hi dedlfix,
Im Kapitel Domain sind alle deine vorhandenen aufgeführt. Unter "Verwendungsart" siehst du, wohin sie zeigen. Und über den Menüpunkt "Verwendungsart bearbeiten" kann man das Documentroot einstellen.
Ja, das schon, ich kann aber nur auf bestehende Verzeichnisse Rooten,
ich hab 2 möglichkeiten,
Verwendungsart - Webspace - oder Weiterleitung
bei Webspace
Aktuelles Verzeichnis /.
Und ein Dropdown Menu mit allen auf meinem Webspace liegenden Verzeichnissen.
Kann das am 1&1 Paket liegen, ich hab ein Basic Paket.
Dateien außerhalb des Documentroot benötigen keine extra Sicherungsmaßnahme, weil es keine URL gibt, um sie abzufragen
S.o.
Das was deine PHP-Scripte im Dateisystem anstellen hat mit dem Webserver, und dem worauf der zugreifen darf, nicht viel gemeinsam. Grundsätzlich kann PHP sämtliche Verzeichnisse erreichen[*], und deren Inhalt in die angeforderte Ressource einbinden.
Danke für die Info, dann kann ich meine Scripte wenigstens ein wenig schützen.
kannst du mir evtl. bei noch ner kleinigkeit einen Tip geben?
Und zwar habe ich jetzt eine details.php die nach übergabe einer ID die
Zellen der übergebenen ID ausliest und ausgibt, nur, wenn man in der URL eine ID reintippt, die es
nicht gibt, bekomme ich eine Fehlermeldung, wie kann ich das beheben?
http://www.nimmet.de/beispiele/phpbsp/dbabfrage.php, auf einen der Interpreten klicken, dann kommt
die detail Seite mit ID.
Grüße,
Engin
GYRO
echo $begrüßung;
Ja, das schon, ich kann aber nur auf bestehende Verzeichnisse Rooten,
Und wer hindert dich, ein Verzeichnis anzulegen? Das "Bestehendes Verzeichnis" sollte sich ausklappen lassen, wobei dann ein "Neues Verzeichnis anlegen" zu sehen ist. Wenn nicht, leg das Verzeichnis über FTP an.
bei Webspace
Aktuelles Verzeichnis /.
Solche Einträge solltest du auf ein Unterverzeichnis umbiegen, denn sonst sind darüber sämtliche Dateien und Verzeichnisse deines Kundenverzeichnisses erreichbar. Und das tut ja nicht not.
Und zwar habe ich jetzt eine details.php die nach übergabe einer ID die
Zellen der übergebenen ID ausliest und ausgibt, nur, wenn man in der URL eine ID reintippt, die es
nicht gibt, bekomme ich eine Fehlermeldung, wie kann ich das beheben?
Ich bekam nur eine leere Seite angezeigt, als ich eine zu hohe ID übergab. Grundsätzlich kannst du natürlich vor einer bestimmten Aktion prüfen, ob dafür auch die notwendigen Daten vorhanden sind. Auch geben dir einige Funktionen durch ihren Rückgabewert zu verstehen, dass eine Abfrage nicht erfolgreich war - z.B. aufgrund eines Fehlers.
Zweiter Versuch: Buchstaben statt einer Zahl. Und da kam ein Fehler, wenn auch nur ein PHP-Folgefehler. Der sagt mir, dass du die Ergebnisse der mysql_*()-Funktionen nicht richtig auswertest. Sattdessen gibst du sie ungeprüft an die Folgefunktion weiter. Das geht nur gut, solange es eben gut geht. Also: Informiere dich gegebenenfalls im Handbuch, was die verwendeten Funktionen im Gut- und was im Fehlerfall zurückliefern und reagiere angemessen auf diese Werte. Und, wie du nebenan im anderen Teilfaden lesen konntest, ist die() keine Erstehilfemaßnahme sondern eine vorsätzliche Tötung.
echo "$verabschiedung $name";
Hi dedlfix,
Zweiter Versuch: Buchstaben statt einer Zahl. Und da kam ein Fehler, wenn auch nur ein PHP-Folgefehler. Der sagt mir, dass du die Ergebnisse der mysql_*()-Funktionen nicht richtig auswertest...Informiere dich gegebenenfalls im Handbuch, was die verwendeten Funktionen im Gut- und was im Fehlerfall zurückliefern und reagiere angemessen auf diese Werte. Und, wie du nebenan im anderen Teilfaden lesen konntest, ist die() keine Erstehilfemaßnahme sondern eine vorsätzliche Tötung.
Stimmt, das hatte ich vergessen zu erwähnen, das nur bei Buchstaben eine Fehlermeldung
erfolgt, werde mich informieren wie ich das im Griff krieg.
Jedenfalls vielen Dank für deine bisherige Hilfe, bin schon Recht weit gekommen
für meine 2 Wochen PHP und Datenbank arbeit. Werde mich jetzt noch um die Details kümmern, mal sehen, wie weit ich komm.
Grüße aus H im R,
Engin
echo $begrüßung;
Stimmt, das hatte ich vergessen zu erwähnen, das nur bei Buchstaben eine Fehlermeldung
erfolgt, werde mich informieren wie ich das im Griff krieg.
Um einen Wert garantiert zu einem Zahlenwert zu machen, gibt es die Funktion intval(). Wenn sie keine Zahl übergeben bekam kommt wenigstens 0 dabei raus.
echo "$verabschiedung $name";
Hi dedlfix,
Um einen Wert garantiert zu einem Zahlenwert zu machen, gibt es die Funktion intval(). Wenn sie keine Zahl übergeben bekam kommt wenigstens 0 dabei raus.
Endlich mal ein begriff, mit dem ich was anfangen kann. :) Dank dir für deine bisherige hilfe.
Grüße aus H im R,
Engin
echo $begrüßung;
[...] für die HTML-Ausgabe stets korrekt kodieren, die Funktionen htmlentities() und htmlspecialcahrs() kennst du nun ja.
Bitte htmlentities() mit Vorsicht genießen. Für den HTML-Kontext ist es ausreichend, htmlspecialchars() zu verwenden. Siehe beispielsweise: </archiv/2008/1/t164688/#m1073706>
if(get_magic_quotes_gpc()) {
$interpret = stripslashes($_POST['interpret']);
$album = stripslashes($_POST['album']);
$songtext = stripslashes($_POST['songtext']);
} else {
$interpret = $_POST['interpret'];
$album = $_POST['album'];
$songtext = $_POST['songtext'];
}
Gut, du hast selber schon festgestellt, dass PHP ein sehr nervendes Feature names magic_quotes besitzt - zum Glück wird dieses ab PHP 6 nicht mehr existieren, deshalb ist es gut, wenn du es hier direkt richtig machst: Falls magic_quotes aktiviert war, mache es mit stripslashes() rückgängig.
Es ist besser, diese Magic-Quotes-Gegenmaßnahme einmalig am Scriptanfang auf die kompletten Eingabedaten-Arrays auszuführen. Am besten mit dem unter http://www.php.net/manual/en/security.magicquotes.disabling.php aufgeführten Beispiel. Erstens hat man damit eine bessere Trennung nach dem EVA-Prinzip, zweitens kann man seinen Quelltext beim Umstieg auf Version 6 einfacher bereinigen, wenn man nur eine Stelle zu berücksichtigen hat statt mehrerer. Außerdem kommt man so nicht auf den dummen Gedanken, für jedes $_POST['foo'] ein $foo benötigen zu müssen. Ein Magic-Quotes-bereinigtes $_POST['foo'] kann man direkt als Parameter einem mysql_real_escape_string() übergeben, ohne eine Zwischenvariable verwenden zu müssen.
Ich habe hier auch noch eine Auswertung der Rückgabe von mysql_query() eingebaut, im Fehlerfall gibt das Script die Fehlermeldung von mysql_error() aus und bricht ab. Im Produktiveinsatz ist das nicht empfehlenswert, zum Debuggen und Entwickeln aber sehr hilfreich.
Die die()-Verwendung ist wirklich nur für Beispiele geeignet. Sobald man ein Script für den Produktiveinsatz schreibt kommt man eigentlich um eine ordentliche Fehlerauswertung und -behandlung nicht umhin. Sich zunächst mit die() zufrieden zu geben, birgt die Gefahr, dass es am Ende im Code drin bleibt. Also am besten gar nicht erst das die() im eigenen Code aufnehmen und noch besser wäre, es auch aus den Beispielen zu verbannen.
if ($result = mysql_query(...)) {
while ($row = mysql_fetch_assoc($result))
...
} else {
// Fehlerbehandlung implementieren!
// genauer Meldungstext mit mysql_error() abfragbar
}
Welche Art der Fehlerbehandlung angemessen ist, muss jeder selbst entscheiden, deswegen habe ich sie hier nur angedeutet statt eine der schlechtesten Varianten (die()) gleich zu implementieren.
$eintragen = mysql_query($eintrag);
if (mysql_affected_rows($eintrag) > 0) {
mysql_query() liefert einen Erfolgsstatus zurück. Man kann ihn direkt auswerten ohne eine weitere Funktion zu bemühen, die im Fehlerfall noch nicht einmal ausgeführt werden kann, weil sie dann ein ungültigen Parameterwert übergeben bekommt. mysql_query() liefert dann nämlich false zurück, mysql_affected_rows() möchte jedoch wie so viele andere mysql_*()-Funktionen eine Ressourcenkennung haben.
echo "$verabschiedung $name";
Die die()-Verwendung ist wirklich nur für Beispiele geeignet. Sobald man ein Script für den Produktiveinsatz schreibt kommt man eigentlich um eine ordentliche Fehlerauswertung und -behandlung nicht umhin. Sich zunächst mit die() zufrieden zu geben, birgt die Gefahr, dass es am Ende im Code drin bleibt. Also am besten gar nicht erst das die() im eigenen Code aufnehmen und noch besser wäre, es auch aus den Beispielen zu verbannen.
Kann man in PHP die() nicht anfangen?
In Perl ist das relativ einfach und läßt sich dadurch gut als Exception-Ersatz gebrauchen.
Struppi.
Hallo Struppi,
Kann man in PHP die() nicht anfangen?
Nein, die () ist im Endeffekt in PHP gleich echo + exit - und exit kann man nicht abfangen.
In Perl ist das relativ einfach und läßt sich dadurch gut als Exception-Ersatz gebrauchen.
Naja, PHP kann ja Exceptions seit Version 5, daher ist das auch unnötig.
Viele Grüße,
Christian
Kann man in PHP die() nicht anfangen?
Nein, die () ist im Endeffekt in PHP gleich echo + exit - und exit kann man nicht abfangen.
Das ist aber blöd. Keine $SIG-Handler?
In Perl ist das relativ einfach und läßt sich dadurch gut als Exception-Ersatz gebrauchen.
Naja, PHP kann ja Exceptions seit Version 5, daher ist das auch unnötig.
Aber wenn ich das richtig versteh nur wenn man OOP arbeitet.
Struppi.
Hallo Struppi,
Nein, die () ist im Endeffekt in PHP gleich echo + exit - und exit kann man nicht abfangen.
Das ist aber blöd. Keine $SIG-Handler?
Es gibt schon Signalhandler für klassische UNIX-Signale (pcntl_signal), aber bei exit wird ja kein Signal erzeugt... Oder was genau meinst Du mit $SIG? (Ich habe irgendwo mal gelesen, dass Perl $SIG auch noch für andere Dinge verwendet, als für UNIX-Signale, aber genau kenne ich mich damit nicht aus)
Naja, PHP kann ja Exceptions seit Version 5, daher ist das auch unnötig.
Aber wenn ich das richtig versteh nur wenn man OOP arbeitet.
Jain. _Werfen_ kann man eine Exception immer (abzüglich Sonderfälle, die aber fast nie relevant sind) - egal ob in einer Include-Datei oder in einer Funktion oder eben in einer Klassenmethode. Die Exception selbst muss allerdings ein Objekt sein, man kann aber auch die Default-Exception-Klasse verwenden, der kann man auch einen numerischen Code & eine Nachricht übergeben, sprich sowas wie throw new Exception ('Nachricht', 1234); funktioniert. Natürlich steckt da auch OOP mit drin, aber man muss keinerlei eigene Klassen definieren oder so etwas, um das zu nutzen.
Viele Grüße,
Christian
Hallo nochmal,
Kann man in PHP die() nicht anfangen?
Nein, die () ist im Endeffekt in PHP gleich echo + exit - und exit kann man nicht abfangen.
dedlfix hat mich gerade im Chat darauf aufmerksam gemacht, dass ich das falsch im Kopf hatte (siehe dazu sein Posting; ich ging davon aus, dass man in register_shutdown_function keine Ausgabe produzieren kann, was offensichtlich nicht stimmt). Zudem hat er mir auch noch gesagt, dass die() und exit() identisch sind (d.h. man exit auch eine Meldung übergeben kann).
Der obige Satz von mir stimmt also gar nicht. ;-)
Viele Grüße,
Christian
echo $begrüßung;
Kann man in PHP die() nicht anfangen?
Kann man. Eine mit register_shutdown_function() registrierte Funktion wird auch nach einen die()/exit() noch abgearbeitet. Allerdings ist dann auch schon der mitgegebenen (Fehlermeldungs-)Text ausgegeben. Den will man ja eigentlich nicht den Anwendern präsentieren. Ebenfalls vorbei ist der HTTP-Header, falls man den noch mit einem Statuscode verschönern wollte. Und, nach einem die() und der Shutdown-Funktion ist definitiv Schluss. Als universale Seite-zu-Ende-Bring-Funktion ist das Konstrukt weniger geeignet, denn man hat ja nicht unbedingt nur ein die() und weiß dann, wie weit die Seite schon aufgebaut war, um noch die restlichen schließenden Strukturen hinzuzufügen. Man kann zwar mehrere Shutdown-Funktionen registrieren, aber der Aufwand, solche zu erstellen und sie situationsgerecht zu registrieren, dürfte den einer "richtigen" Fehlerbehandlung überschreiten. Dazu kommt noch die Unübersichtlichkeit des Gesamtablaufs und dass eine einmal registrierte Shutdown-Funktion sich nicht mehr entfernen lässt. Wer sich solch ein Konstrukt ausdenkt und pflegen möchte, nur um ein paar die() anwenden zu können, dem ist nicht mehr zu helfen :-)
echo "$verabschiedung $name";
echo $begrüßung;
Kann man in PHP die() nicht anfangen?
Kann man. Eine mit register_shutdown_function() registrierte Funktion wird auch nach einen die()/exit() noch abgearbeitet. Allerdings ist dann auch schon der mitgegebenen (Fehlermeldungs-)Text ausgegeben. ... Wer sich solch ein Konstrukt ausdenkt und pflegen möchte, nur um ein paar die() anwenden zu können, dem ist nicht mehr zu helfen :-)
Das klingt wirklich schlimm.
Ich kenn es nur von Perl und da ist die() ein probates Mittel und Fehler mitzuteilen und diese lassen sich mittles $SIG{__DIE__} = sub {} auch abfangen. Genau wie warn. Damit ist eine sehr vielschichtige Fehlerdiagnose möglich, die sich sogar im produktiv Einsatz benutzen läßt (ich lass mir z.b. die die() Meldungen als e-mail schicken)
Struppi.
echo $begrüßung;
Ich kenn es nur von Perl und da ist die() ein probates Mittel und Fehler mitzuteilen und diese lassen sich mittles $SIG{__DIE__} = sub {} auch abfangen. Genau wie warn. Damit ist eine sehr vielschichtige Fehlerdiagnose möglich, die sich sogar im produktiv Einsatz benutzen läßt
Das sieht mir aber eher nur nach einem Diagnosewerzeug statt nach einer geplanten Reaktion auf vorhersehbare Fehler aus. (Dass eine Datenbank mal nicht erreichbar ist, ist beispielsweise ein vorhersehbarer Fehler.) Ziel sollte immer sein, dass ein Script an seinem Ende ankommt. Dabei darf es gelegentlich Umwege nehmen, auch wenn diese die Hauptattraktion umfahren. Das ist immer noch besser als mit Motorschaden auf der Strecke liegenzubleiben.
ich lass mir z.b. die die() Meldungen als e-mail schicken
Man kann sich unter PHP eine eigene ErrorHandler-Funktion (für alle nicht-fatalen Fehler) schreiben und mit set_error_handler() aktivieren. In diesem ErrorHandler kann man sich beispielsweise eine E-Mail schicken lassen. Diese Funktion wird bei jedem Auftreten eines PHP-Fehlers aufgerufen. Der Programmablauf wird dabei aber nicht abgebrochen. Nach Ende der ErrorHandler-Funktion geht es weiter im Kontext des Hauptscripts.
MySQL-Fehler sind ja erstmal keine PHP-Fehler, weswegen bei einem solchen der ErrorHandler zunächst nicht anspringt - erst bei Folgefehlern, doch dann fehlt einem der eigentliche Fehlerauslöser inklusive dessen Wortlaut. Nun könnte man annehmen, das die() durch ein trigger_error() auszutauschen. Dann bekommt man zwar einen Aufruf des ErrorHandlers inklusive eine "Maildung" nach Hause, läuft dann aber im Hauptscript fröhlich in Folgefehler.
Der eigene ErrorHandler ist also auch kein Ersatz für eine Fehlerbehandlung. Er kann lediglich ein zusätzliches Hilfsmittel sein, um auf Probleme aufmerksam zu machen, die sonst nur die Anwender zu Gesicht bekommen.
echo "$verabschiedung $name";
Ich kenn es nur von Perl und da ist die() ein probates Mittel und Fehler mitzuteilen und diese lassen sich mittles $SIG{__DIE__} = sub {} auch abfangen. Genau wie warn. Damit ist eine sehr vielschichtige Fehlerdiagnose möglich, die sich sogar im produktiv Einsatz benutzen läßt
Das sieht mir aber eher nur nach einem Diagnosewerzeug statt nach einer geplanten Reaktion auf vorhersehbare Fehler aus.
Kann sein, dass ich nicht richtig gelesen habe worum es ging.
Ich möchte natürlich hier nicht propagieren die() für alle Arten von vorhersehbaren Fehlern zu verwenden, in dem Fall ist eine ordentliche Prüfung von Rückgabewerten und eine entsprechende Behandlung natürlich sinnvoller.
(Dass eine Datenbank mal nicht erreichbar ist, ist beispielsweise ein vorhersehbarer Fehler.)
Naja, und durchaus einer, der zum Abbruch eines Skriptes führen könnte. Ohne Daten sind die meisten Sachen nicht mehr sinnvoll. D.h. ein die() das eine HTML Fehlerseite ausgibt und an eine Mail an den Admin verschickt, wäre hier die richtige Reaktion (es sei denn man hat mehrere DB Server, es gäbe natürlich auch die Möglichkeit es nochmals zu versuchen, was ich aber bei meinem Perl Skripten nicht machen würde, da dort oft die Laufzeit so beschränkt ist, dass das Skript aus diesem Grund abgebrochen werden könnte)
Ziel sollte immer sein, dass ein Script an seinem Ende ankommt. Dabei darf es gelegentlich Umwege nehmen, auch wenn diese die Hauptattraktion umfahren. Das ist immer noch besser als mit Motorschaden auf der Strecke liegenzubleiben.
Ja sicher, bei weniger fatalen Problemen ist das sicher möglich und sinnvoll.
Aber du hast recht, die() ist natürlich in erster Linie zu Diagnosezwecke vorhanden, dient also eher dem Programmierer Fehler zu erkennen und vermeiden und nicht um dem Anwender falsche Eingabe oder andere Bedienungsfehler u die Ohren zu hauen.
ich lass mir z.b. die die() Meldungen als e-mail schicken
set_error_handler()... Diese Funktion wird bei jedem Auftreten eines PHP-Fehlers aufgerufen. Der Programmablauf wird dabei aber nicht abgebrochen. Nach Ende der ErrorHandler-Funktion geht es weiter im Kontext des Hauptscripts.
Was natürlich dem die() aufruf entgegen spricht, es geht ja gerade darum Folgefehler zu vermeiden ansonsten würde man ja nicht sterben wollen und eben Programmierfehler zu erkennen.
Struppi.
echo $begrüßung;
(Dass eine Datenbank mal nicht erreichbar ist, ist beispielsweise ein vorhersehbarer Fehler.)
Naja, und durchaus einer, der zum Abbruch eines Skriptes führen könnte. Ohne Daten sind die meisten Sachen nicht mehr sinnvoll. D.h. ein die() das eine HTML Fehlerseite ausgibt und an eine Mail an den Admin verschickt, wäre hier die richtige Reaktion
Deine Betrachtungsweise setzt voraus, dass man nach dem EVA-Prinzip vorgegangen ist. Man sucht sich also zunächst seine Daten zusammen und erst dann geht man zur Ausgabe über. Dann kann man im Falle eines Fehlerfalles auch per die() und register_shutdown_function() eine komplette Fehlerseite ausgeben und ist aus HTML-Sicht sauber. Doch oftmals hängt ja gerade bei PHP-Anfängern die Datenbankabfrage an der Stelle im HTML-Gerüst, an der die Ergebnisse dargestellt werden sollen. Es ist ja bei PHP so einfach, aus dem HTML auszubrechen und mal eben PHP-Code einzufügen. Für dieses Prinzip ist es ja erfunden worden. (Und man findet es beispielsweise auch bei JSP und ASP.) Wenn man erst einmal an einer solchen Stelle im HTML-Gerüst angelangt ist, ist korrektes Beenden des HTML-Dokuments mittels die() und r.s.f() ein nicht einfaches Unterfangen.
Ziel sollte immer sein, dass ein Script an seinem Ende ankommt. Dabei darf es gelegentlich Umwege nehmen, auch wenn diese die Hauptattraktion umfahren. Das ist immer noch besser als mit Motorschaden auf der Strecke liegenzubleiben.
Ja sicher, bei weniger fatalen Problemen ist das sicher möglich und sinnvoll.
Da, scheint mir, haben wir eine unterschiedliche Auffassung von fatal. Für mich ist es fatal, wenn gar nichts mehr geht. Der Tag ist für mich nicht beendet, wenn sich herausstellt, dass mein Hauptvorhaben undurchführbar ist. Ich verbringe dann die Zeit bis 24 Uhr mit einem Ersatzprogramm und erschieße mich nicht gleich :-) Das gleiche sollte man seinen Besuchern anbieten. "Es tut uns leid, ein Fehler ist aufgetreten." - Und nun? Der Besucher hatte ein Ziel. Wie erreicht er es trotzdem? Welche Alternativen kann man ihm anbieten? Ist es nicht besser, ihm als Ersatz die Bestellung per Mail oder Fax anzubieten statt mit einem "Geht grad nicht" auf das Geschäft zu verzichten?
[...] es geht ja gerade darum Folgefehler zu vermeiden ansonsten würde man ja nicht sterben wollen und eben Programmierfehler zu erkennen.
Das ist der Dreh- und Angelpunkt. Es geht um die Art der Folgefehlervermeidung. Wenn ich eine Erkältung habe, dann gehe ich zu Bett, um den Folgefehler Lungenentzündung zu vermeiden. Ich gehe aber nicht sofort sterben, auch wenn dann von irgendeiner Instanz ein ordentliches Begräbnis ausrichtet wird. Mein Ziel ist es, auf Alternativen zur Gnadenschussmentalität hinzuweisen. Else statt Exit! :-)
echo "$verabschiedung $name";
Naja, und durchaus einer, der zum Abbruch eines Skriptes führen könnte. Ohne Daten sind die meisten Sachen nicht mehr sinnvoll. D.h. ein die() das eine HTML Fehlerseite ausgibt und an eine Mail an den Admin verschickt, wäre hier die richtige Reaktion
Deine Betrachtungsweise setzt voraus, dass man nach dem EVA-Prinzip vorgegangen ist. ... Wenn man erst einmal an einer solchen Stelle im HTML-Gerüst angelangt ist, ist korrektes Beenden des HTML-Dokuments mittels die() und r.s.f() ein nicht einfaches Unterfangen.
Stimmt, ich benutze das EVA Prinzip (wußte gar nicht dass das so heißt), u.a. aus eben den von dir gennanten Gründen.
Ja sicher, bei weniger fatalen Problemen ist das sicher möglich und sinnvoll.
Da, scheint mir, haben wir eine unterschiedliche Auffassung von fatal. Für mich ist es fatal, wenn gar nichts mehr geht. Der Tag ist für mich nicht beendet, wenn sich herausstellt, dass mein Hauptvorhaben undurchführbar ist. Ich verbringe dann die Zeit bis 24 Uhr mit einem Ersatzprogramm und erschieße mich nicht gleich :-) Das gleiche sollte man seinen Besuchern anbieten. "Es tut uns leid, ein Fehler ist aufgetreten." - Und nun? Der Besucher hatte ein Ziel. Wie erreicht er es trotzdem? Welche Alternativen kann man ihm anbieten? Ist es nicht besser, ihm als Ersatz die Bestellung per Mail oder Fax anzubieten statt mit einem "Geht grad nicht" auf das Geschäft zu verzichten?
Das ist ungefähr das was ich gesagt habe. Wenn das technische Problem so gross ist, dass eine weitere Ausführung des Skripts nicht mehr möglich ist, sterbe und geb dem Besucher eine entsprechende Fehlerseite aus.
Wenn man dann die Möglichkeiten hat einen Ersatz anzubieten umso besser. Das läßt sich aber eben nur mit die() (zumindest unter Perl) erreichen, da es so möglich ist aus den Tiefen der Modulen eine zentrale Fehlerbehandlung zu verwenden, die dann entsprechend reagieren kann.
[...] es geht ja gerade darum Folgefehler zu vermeiden ansonsten würde man ja nicht sterben wollen und eben Programmierfehler zu erkennen.
Das ist der Dreh- und Angelpunkt. Es geht um die Art der Folgefehlervermeidung. Wenn ich eine Erkältung habe, dann gehe ich zu Bett, um den Folgefehler Lungenentzündung zu vermeiden. Ich gehe aber nicht sofort sterben, auch wenn dann von irgendeiner Instanz ein ordentliches Begräbnis ausrichtet wird. Mein Ziel ist es, auf Alternativen zur Gnadenschussmentalität hinzuweisen. Else statt Exit! :-)
Bei weniger fatalen Gesundheitsproblemen ist das der Weg, ja. Eine Erkältung ist sicher für wenige Leute ein Grund sich zu erschiessen, es gibt aber Situationen wo es eine Überlegung Wert ist. Daher nur sterben, wenn es gar nicht anders geht! Und eine Himmelspforte bereithalten.
Struppi.