Eintrag in Datenbank klappt nicht
Tommy
- php
Hallo,
ich bin grad dabei den Umgang mit Datenbanken zu lernen (MySQL) und habe hier ein Buch mit Beispielen, wie man die Verbindung zu einer DB aufbaut, Inhalte abruft usw.
Soweit klappt alles, bis auf das Eintragen von neuen Daten mittels Formular.
Das Script liegt auch so wie im Buch beschrieben auf einer CD vor - wenn ich mich also irgendwo verschrieben haben sollte, dann wäre auf der CD der gleiche Fehler vorhanden, denn das Ergebnis sieht identisch aus: es werden keine Daten in die DB geschrieben. Eine Fehlermeldung erhalte ich aber auch nicht.
Kurzzusammenfassung des Scripts:
Als Beispiel wird eine Linkliste erzeugt, es gibt die Felder:
id, url, urlname, name, banner, beschreibung
Über folgende Dateien soll der Eintrag geschehen:
dbconnect.php (Verbindung zur DB Herstellen, das klappt):
<?php
$server = "localhost";
$user = "...";
$pass = "...";
$datenbank = "...";
$verbindung = mysql_connect($server,$user,$pass);
mysql_select_db($datenbank);
?>
eintragen.php (Script, um in die DB zu schreiben und die Werte anschließend ausgeben zu lassen; Ausgabe klappt, aber außer "von" aus der letzten "echo-Zeile" sehe ich nichts, es wird nur jeweils eine neue ID angelegt, aber in den Spalten steht nichts [kontrolliert mit phpMyAdmin; hier manuell eingetragene Werte werden korrekt ausgegeben]):
<?php
include("dbconnect.php");
$eintrag = "INSERT INTO links (url, urlname, name, banner, beschreibung) VALUES ('$url', '$urlname', '$name', '$banner', '$beschreibung')";
$eintragen = mysql_query($eintrag);
# gibt DB-Inhalt aus:
$abfrage = "SELECT * FROM links";
$ergebnis = mysql_query($abfrage);
while($row = mysql_fetch_object($ergebnis))
{
echo "<a href='$row->url'>";
echo $row->urlname;
echo "</a>\n";
echo "<br>";
echo $row->beschreibung ." von ". $row->name ."<br><br>";
}
?>
Und zuletzt, das Formular:
<html>
<head>
<title>Link eintragen</title>
</head>
<body>
<form action="eintragen.php" method="POST">
<br>URL:
<br>
<input type="text" name="url" maxlength="100">
<br>URL-Name:
<br>
<input type="text" name="urlname" maxlength="250">
<br>Name:
<br>
<input type="text" name="name" maxlength="100">
<br>Banner-URL:
<br>
<input type="text" name="banner" maxlength="250">
<br>Beschreibung:
<br>
<textarea cols="40" rows="5" name="beschreibung"></textarea>
<br><br>
<input type="submit" value="Eintragen">
</form>
</body>
</html>
Woran liegt das? Das Script müsste ja stimmen. Tabellenname "links" sowie alle Feldnamen stimmen und sind in der korrekten Reihenfolge.
Ein altes Buch ?
REGISTER_GLOBALS ist dein Problem und offensichtlich
auf off gestellt.
Bedeutet: Machs mal so
$eintrag = "INSERT INTO links (url, urlname, name, banner, beschreibung)
VALUES ($_POST[url], ......)";
Ein altes Buch ?
Ein wenig, 2002.
Bedeutet: Machs mal so
$eintrag = "INSERT INTO links (url, urlname, name, banner, beschreibung)
VALUES ($_POST[url], ......)";
Da tut sich gar nichts (wird in der DB auch keine neue Zeile angelegt) :(
VALUES ($_POST[url], ......)";
Ich hoffe du hast das nicht 1:1 kopiert sondern schon die
values weitergeführt ?
Ok nochmal,
Aber zuerst setze mal oben im Script Folgendes ein:
ini_set('error_reporting', E_ALL);
Damit siehst du Fehler , kannst du später wieder entfernen.
Die Zeilen mal anders zum testen.
If($_POST){echo'<pre>';print_r($_POST);echo'</pre>';}
extract($_POST);
$eintrag = "INSERT INTO links (url, urlname, name, banner,beschreibung)
VALUES ('$url', '$urlname', '$name', '$banner', '$beschreibung')";
» Ich hoffe du hast das nicht 1:1 kopiert sondern schon die values weitergeführt ?
Ja, das hab ich noch hinbekommen ;)
» ini_set('error_reporting', E_ALL);
Fehler gibt er in beiden Varianten ($url und $POST[url]) nicht aus.
» Die Zeilen mal anders zum testen.
»
» If($_POST){echo'<pre>';print_r($_POST);echo'</pre>';}
» extract($_POST);
»
Wenn das drinsteht funktioniert es (und gibt mir auch die korrekten Daten aus):
Array
(
[url] => http://
[urlname] => seitenname
[name] => der name
[banner] => banner.gif
[beschreibung] => blabla
)
~~~.
Funktioniert aber nur mit "meiner" Variante.
Funktioniert aber nur mit "meiner" Variante.
Ja, natürlich.
Durch das extract($_POST) hebst du REGISTER_GLOBALS=OFF
wieder auf, was aber nicht im Sinne des Erfinders ist.
Also muss diese Variante auch klappen:
$url = $POST['url'];
$urlname = POST['urlname'];
$name = POST['name'];
$banner = POST['banner'];
$beschreibung = POST['beschreibung'];
/// wenn das klappt hast du es eben die Values falsch fortgeführt.
$eintrag = "INSERT INTO links (url, urlname, name, banner,beschreibung)
VALUES('$url', '$urlname', '$name', '$banner', '$beschreibung')";
Natürlich jetzt ohne extract.
Ja, die neue Variante klappt.
Und, es klappt auch so '$_POST[url]'
Da haben lediglich die Hochkommas gefehlt (also, in deiner ersten Antwort ;) - oder ich habs doch nicht wie erwartet "hinbekommen").
Nun das läuft, vielen Dank :)
Gern geschehen ;-)
Schön wenn Jemand noch Zeit findet, zu erklären
dass es geklappt hat, passiert hier nicht oft.
Nun, eigentlich wollte ich dich nur noch auf deinen Fehler hinweisen .. :D
Nein, Spaß beseite - wenn ich hier einfach so von dannen zieh, krieg ich ja vermutlich beim nächsten Mal nur noch halb so viele Antworten ;)
Und eigentlich, ist sowas doch selbstverständlich - der Helfer hilft ja auch bis zum Schluss :)
echo $begrüßung;
VALUES ($_POST[url], ......)";
Wenn man Array-Werte in mit "" eingefassten Strings unterbringen möchte, muss man {}-Klammern verwenden. $string = "Ein Text mit einer {$array['variablen']} drin.";
Allgemein ist dieses Vorgehen, Benutzereingaben direkt in SQL-Stements unterzubringen, jedoch nicht anzuraten. (Fortsetzung dieses Themas weiter unten)
ini_set('error_reporting', E_ALL);
Um das error_reporting zu setzen kann man auch die eigens dafür existierende Funktion error_reporting() verwenden.
Damit siehst du Fehler, kannst du später wieder entfernen.
Konkreter: Mit der Voreinstellung des error_reporting-Wertes werden E_NOTICE-Meldungen nicht ausgegeben. Eine solche wird erzeugt, wenn man auf nicht vorhandene Variablen lesend zugreifen möchte. Sehr nützlich bei Tippfehlern in Variablennamen, und eben auch in diesem Fall, wenn man auf Variablen zugreift, die nicht angelegt wurden, weil register_globals ausgeschaltet war.
$eintrag = "INSERT INTO links (url, urlname, name, banner, beschreibung)
VALUES ('$url', '$urlname', '$name', '$banner', '$beschreibung')";
Ungeprüfte Benutzereingaben direkt in SQL-Statements einzubinden ist eine potentielle Sicherheitslücke und kann auch bei "gutmütigen Daten" zu Fehlern führen. Nehmen wir mal an, jemand hat als Name O'Conner eingegeben. Wie sieht dann der Wert von $eintrag aus?
INSERT INTO links (...) VALUES ('eine url', ..., 'O'Conner', ...)
Das ist fehlerhaft, weil --------------------------^ da der vor dem O begonnene String aufhört. Kritischer ist es, wenn man bei Authentifizierungsabfragen ebenso lasch behandelt. Da kann dann schon mal bei weniger gutmütigen Daten sowas bei rauskommen
SELECT felder FROM users WHERE name='irgendwas' OR '1' AND password='irgendwas';
Als Name wurde irgendwas' OR '1 eingegeben. Durch das Nichtentschärfen der ' wird hier der der Befehl um ein OR '1' erweitert, was die WHERE-Bedingung immer true werden lässt. Als Ergebnis erhält man dann alle Datensätze statt nur einem oder keinem. Meist prüft der Anfänger dann auch nur ob entweder keiner existiert (z.B. wegen falschen Passworts) oder greift blind auf den ersten Satz des Ergebnisses zurück. Der Angreifer erwischt mit Glück den Admin-Account, denn der ist oftmals der zuerst eingetragene.
Es gibt ein PHP-Feature namens Magic Quotes, das diese SQL-Injection unterbinden soll, indem es einigen Zeichen ein \ voranstellt. Doch dieses Feature ist zu allgemein gehalten. Es entschärft zu wenig Zeichen, und manchmal benötigt man es gar nicht, weil die Daten einem anderen Medium mit anderen Maskierungsvorschriften übergeben werden sollen. (Zudem wird dieser Automatismus ab PHP6 nicht mehr vorhanden sein.)
Doch wie macht man es nun besser? Man verwende die für das jeweilige Ausgabemedium passende Maskierung. Die MySQL-API stellt dafür die Funktion mysql_real_escape_string() zur Verfügung. Zusammen mit sprintf() sieht ein übersichtliches INSERT-Statement beispielsweise so aus:
$eintrag = sprintf("INSERT INTO links (url, urlname, name, banner,beschreibung) " .
"VALUES ('%s', '%s', '%s', '%s', '%s')",
mysql_real_escape_string($_POST['$url']),
mysql_real_escape_string($_POST['$urlname']),
mysql_real_escape_string($_POST['$name']),
mysql_real_escape_string($_POST['$banner']),
mysql_real_escape_string($_POST['$beschreibung']));
Sollte Magic Quotes eingeschaltet sein, muss man es nun auschalten oder dessen Auswirkungen (am Scriptanfang) rückgängig machen: Disabling Magic Quotes.
echo "$verabschiedung $name";
hi,
Bedeutet: Machs mal so [...]
VALUES ($_POST[url], ......)";
$_POST['url'] meinst du.
gruß,
wahsaga