FB18 - Das Forum für Informatik

fb18.de / Off-Topic / Allgemeines

PHP & MySQL, frage zum UPDATE Befehl

PHP & MySQL, frage zum UPDATE Befehl 2007-05-22 20:52
Morpheus
ich habe ein scheinbar einfaches problem das mir nun aber seit 2 stunden kopfzerbrechen verschafft: ich versuch in einer bereits vorhanden tabelle in eine MySQL DB einen eintrag upzudaten, leider verweigert mir MySQL den gehorsam und ich kann nicht den fehler finden.

hier der code:
$sql = "UPDATE ". $_POST["Projekt"]. " SET ". "(Methode1 = '".$output14."')". " WHERE ". "(Id = '".$_POST["Id"]."')"; mysql_query ($sql); echo $sql . ": " . mysql_errno() . ": " . mysql_error(). "\n";
hier die fehlerausgabe:
UPDATE projekt1 SET (Methode1 = 'output14') WHERE (Id = '13'): 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(Methode1 = 'output14') WHERE (Id = '13')' at line 1
ich benutze das neuste XAMPP. wenn ihr mir helfen könntet wär das grossartig, ich soll eigentlich bis morgen den kram fertig haben. falls ihr noch mehr info braucht bitte nachfragen. thx im vorraus.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-22 20:59
Wulf
seit wann kommen denn () nach dem SET? nie gesehen..

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-22 21:16
Morpheus
ahem joaaa… also ums kurz zu machen: da war der schon der fehler. klammern weg und es hat geklappt. zu meiner verteidigung: ich habs so beigebracht bekommen, zB funzt
$sql = "SELECT ". "Input, Zwischenergebnis1, Zwischenergebnis2, Zwischenergebnis3, Output ". "FROM ". methode11. " WHERE ". "(Input like '".$input11."') AND ". "(Zwischenergebnis1 like '".$zwischenergebnis111."') AND ". "(Zwischenergebnis2 like '".$zwischenergebnis112."') AND ". "(Zwischenergebnis3 like '".$zwischenergebnis113."') AND ". "(Output like '".output11."')"; $result = mysql_query ($sql); ohne probleme. ich musste aber zum ersten mal UPDATE benutzen, kann natürlich gut sein dass das bei SET eine ausnahme ist.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-22 22:20
Wulf
naja, das nach WHERE ist quasi ein boolescher Ausdruck und kann somit beliebig geklammert werden.

Aber was anderes: Ich hoffe doch, dass $input11 und so durch mysql_real_escape_string o.ä. gelaufen ist?
Oder du benutzt besser gleich die Bind/Parameter Funktionalität in mysqli.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-23 13:19
joda_der_weise
Vorrausgesetzt mysqli ist als Modul geladen undverfügabr… ;)

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-24 17:19
Anonymer User
$sql = "UPDATE ". $_POST["Projekt"]. " SET ". "(Methode1 = '".$output14."')". " WHERE ". "(Id = '".$_POST["Id"]."')"; mysql_query ($sql);
Bissle Offtopic:
Musst du PHP benutzen? PHP hat so eine unglaublich schlechte und Fehlertraechtige DB Anbindung :( So schleichen schnell Fehler und Bugs ein. So auch hier. Wie schon angemekrt, moechtest du die POST Parameter escapen, sonst hacked man dir die DB… Python ist schoen. Es gibt eine huebsche DBAPI und man kann nur schwer was falsch machen. Darueberhinaus kann man ziemlich simpel die DB dadrunter tauschen ohne das man am Code was veraendern muss *sigh*

hier die fehlerausgabe:
UPDATE projekt1 SET (Methode1 = 'output14') WHERE (Id = '13'): 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(Methode1 = 'output14') WHERE (Id = '13')' at line 1

Die SQL Fehlermeldung geht beim Fehler los. Das ist hier bei dir die oeffnende Klammer.
Hast ud es jemals ohne den geklammerten SET ausdruck da probiert?!

Noch ein Tipp: Wenn du phpMyAdmin benutzt, kannst du dir die verwendendeten SQL Statements anschauen lassen…

MfG
Muelli

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-25 08:02
joda_der_weise
Ich würde mich Muelli nicht anschliessen!
PHP ist für MySQL sehr simpel, intuitiv lesbar und auch hier kann ich bei richtiger Programmierung die DB schnell und einfach austauschen…

Ein kleiner Tip zur "Scheibweise":
Man kann in PHP die Variablen in den " " direkt schreiben ohne Concatenieren zu müssen, aber dann unter bestimmter Syntax. Hier Dein Beispiel (gleich korrigiert):

$sql = "UPDATE $_POST[Projekt] SET `Methode1` = '$output14'. WHERE `Id` = '$_POST[Id]')"; mysql_query ($sql);
Übrigens:
Es ist nicht sonderlich schlau die DB per POST zu übergeben.
Kannst Du das nicht anders machen?

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-25 17:33
UncleOwen
Ich würde mich Muelli nicht anschliessen!

Und dann lieferst Du ein weiteres Beispiel, wie man unsicheren Code in PHP schreibt…

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-26 03:18
Muelli
Ich würde mich Muelli nicht anschliessen!
PHP ist für MySQL sehr simpel, intuitiv lesbar und auch hier kann ich bei richtiger Programmierung die DB schnell und einfach austauschen…
Ich hab ja auch gar nichts gegenteiliges gesagt. Lediglich, dass es "[…] so eine unglaublich schlechte und Fehlertraechtige DB Anbindung :( [hat]".

Und du hast vielleicht recht, wenn du sagt, dass man das evtl. schnell und einfach austauschen KANN. Aber ich behaupte, dass ich noch keinen PHP Code gesehen hab', bei dem man das kann. (Frameworks ausgeschlossen, sowas seh ich mir nicht an…) Du musst mindestens die mysql_query() funktion auswechseln. Wie bloed. Mit der DBAPI in Python importiere ich bloss eine andere Datenbank und bin mit allem (! also was die DB Anbindung, die Queryuebergabe, die Parameteruebergabe, das Escaping, …) durch.
e.g.: tausche "import MySQLdb as dbapi2" gegen "import sqlite3.dbapi2 as dbapi2" und alles ist gut[1].

$sql = "UPDATE $_POST[Projekt] SET `Methode1` = '$output14'. WHERE `Id` = '$_POST[Id]')"; mysql_query ($sql);
aahhh.
:( Naja. Aber so gehen wenigsetns keine Arbeitsplaetze fuer Webapp Programmierer und Pentester verloren…

Du benutzt weder SQL noch PHP korrekt.
Deine Abfrage duerfte lediglich mit MySQL kompatibel sein (aufgrund der Backticks, die zB SQLite nicht kennt und IIRC in keinem SQL Standard stehen) und gibst schamlos, wie UO angedeutet hat, Userinput an die DB…

Den einzigen (vermeindlichen) Vorteil, den ich an PHP sehe ist, dass es an jeder Ecke billige und guenstige Programmierer gibt…

MfG
Muelli

[1] vorrausgesetzt natuerlich, der Code ist sauber und hat keine fiesen unportablen Dinge. Aber das ist in Python um einiges leichter als in PHP.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-26 10:34
Popcorn
Und du hast vielleicht recht, wenn du sagt, dass man das evtl. schnell und einfach austauschen KANN. Aber ich behaupte, dass ich noch keinen PHP Code gesehen hab', bei dem man das kann.
Wenn Du mit PHP objektorientiert programmierst, kannst Du Dir einmalig Module erstellen (vielleicht gibt es auch schon fertige bei PEAR?). Ich mache das selbst gerade und brauch in meinem Programm selbst auch nur im Konfigurationsfile, einmalig etwa zwischen

require_once 'classes/MySQL.php';
$db = new MySQL($db_server, $db_user, $db_password, $db_name);

require_once 'classes/db_postgre.php';
$db = new db_postgres($db_server, $db_user, $db_password, $db_name);

tauschen, bzw. umkommentieren. Allerdings bin ich auf dem Gebiet außerhalb von MySQL total unwissend. Demnächst probiere ich es noch mal mit Oracle, dass es da doch noch Probleme gibt, will ich nicht ausschließen, aber vom Prinzip her…

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-27 09:27
joda_der_weise
Jap,

mit einer DB-Klasse (ab PHP 5 gar kein Problem mehr) ist es ganz einfach die Anbindung auszutauschen.
Die DB-Klasse kümmert sich dann um Deine Anbindung an die verschiedenen DBs (also Oracle, MySQL, etc.) und baut dann auch diesen "fehlerhaften Code" richtig zusammen, was dann die Frage nach der DB komplett egal macht…
Die Lesbarkeit von Code ist ein ganz wichtiger Faktor.
PHP interpretiert in " " Anweisungen Variablen bzw. gibt deren Wert innerhalb dieser Blöcke aus (z. B. in print ("") ) und das sollte man dann doch tunlichst nutzen…

Natürlich muss dafür dann eine Variablenvobereitung (sei es escaping oder Time-Formating) davor passieren oder halt concateniert werden…

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-28 13:07
Muelli
Aha. Also muss ich mir erstmal eine DB Klasse zusammenbauen m vernuenftig mit DBn umgehen zu koennen…

… Aber wie escapest du Argumente fuer deine Statements? sowas wie
$sql = "SELECT name, nummer FROM phonebook WHERE name = '" . mysql_real_string_escape($_POST[name]) . "' ; $db->query($sql) wird ja nicht gehen, wenn du ein DB unanhaengiges Interface gebaut hast.

Also musst du (sic!) etwas bauen, was Parameter annimmt und in dein Query escaped und einbaut. Schliesslich gibt es zu jeder DB ein anderes Escaping (das Wort gibt es bestimmt gar nicht, aber man weiss, was ich meine, oder?).

Man koennte wohl alternativ sowas bauen wie
$sql = "SELECT name, nummer FROM phonebook WHERE name = '" . $db->escape($_POST[name]) . "' ; $db->query($sql) Aber ich finde es sehr schade, dass ich sowas selber bauen muesste und dass es dann so haesslich wird.

In Python (*fg*) baue ich mein Statement ungefaehr so:
sql = "SELECT name, nummer FROM phonebook WHERE name = ?" args = ("John",) db.cursor.execute(sql, args) result = cursor.fetchone() *sigh*

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-28 13:17
Popcorn
Aha. Also muss ich mir erstmal eine DB Klasse zusammenbauen m vernuenftig mit DBn umgehen zu koennen…
Ich weiß nicht, vielleicht gibt es auch fertige. In anderen Sprachen ist es ja auch kein Voodoo, sondern wurde nur von den Entwicklern hergestellt. Meine Klasse ist derzeit noch ziemlich Beta, aber inklusive Kommentare funktioniert das grundsätzliche auf 75 normalen Zeilen. Im Prinzip nimmt man nur den Inhalt und packt ihn in der Datenbank entsprechende Funktion.

… Aber wie escapest du Argumente fuer deine Statements? sowas wie
$sql = "SELECT name, nummer FROM phonebook WHERE name = '" . mysql_real_string_escape($_POST[name]) . "' ; $db->query($sql) wird ja nicht gehen, wenn du ein DB unanhaengiges Interface gebaut hast.
Das geht nun wirklich ganz einfach. Es heißt dann nur nicht .mysql_real_string_escape($_POST[name]), sondern . $db->escape($_POST[name]).

public function escape($string) { return mysql_real_escape_string($string); }
Also musst du (sic!) etwas bauen, was Parameter annimmt und in dein Query escaped und einbaut. Schliesslich gibt es zu jeder DB ein anderes Escaping (das Wort gibt es bestimmt gar nicht, aber man weiss, was ich meine, oder?).
Im Deutschen spricht man dann vom Maskieren. Also wie gesagt, der Dreizeiler da oben… Ich meine, ich bin ja auch faul, aber das ist doch etwas zu viel des Guten. Besonders weil man für die nächsten Datenbanken tatsächlich nur noch den Funktionsnamen austauschen braucht.

Man koennte wohl alternativ sowas bauen wie
$sql = "SELECT name, nummer FROM phonebook WHERE name = '" . $db->escape($_POST[name]) . "' ; $db->query($sql) Aber ich finde es sehr schade, dass ich sowas selber bauen muesste und dass es dann so haesslich wird.
Ähm. Schreib das doch eher, dann hätte ich das nicht schreiben brauchen. Wieso hässlich? So sieht OO-Code nun mal aus.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-05-28 13:30
TriPhoenix
Muelli, du glaubst doch nciht ernsthaft das snoch keiner ne generische Datenbankabstraktion geschrieben hat und du die selber schreiben musst? PEAR z.B. liefert ne Datenbankabstraktionsklasse DB mit nem Stapel Untermodule. Die bringt dann naütrlich auch eine generische Methode escapeSimple(), die von jeder Unterklasse ausgefüllt wird. Aber prepared Statements sind eh cooler, also:

In Python (*fg*) baue ich mein Statement ungefaehr so:
sql = "SELECT name, nummer FROM phonebook WHERE name = ?" args = ("John",) db.cursor.execute(sql, args) result = cursor.fetchone() *sigh*

$sth = $db->prepare('SELECT name, nummer FROM phonebook WHERE name = ?'); $data = array("John"); $res = $db->execute($sth, $data); $data = $res->fetchRow();
Das ist also weder ein Argument für Python, noch gegen PHP ;) Gut funktionierende Abstraktionen liefern die meisten Sprachen inzwischen, man muss sie nur benutzen.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-06-07 02:06
Muelli
Muelli, du glaubst doch nciht ernsthaft das snoch keiner ne generische Datenbankabstraktion geschrieben hat und du die selber schreiben musst?
Ach Tri.

Solange wie der offizielle Weg, eine Datenbankverbindung ueber die einzelnen Funktionen, ohne Abstaktion und vernuenftigem Escaping geht, solange macht es PHP dem (unerfahrenen) Programmier immer viel zu leicht machen, schlechte Anwendungen zu schreiben.


PEAR z.B. liefert ne Datenbankabstraktionsklasse DB mit nem Stapel Untermodule. Die bringt dann naütrlich auch eine generische Methode escapeSimple(), die von jeder Unterklasse ausgefüllt wird.
nunja, ich waere eher schockiert gewesen, wenn sowas ueberhaupt nicht moeglich waere. Aber s.o.: Der Programmierer wird fast provoziert, die schlechten PHP Stammfunktionen zu nehmen. Es gibt nicht mal einen bloeden Hinweis auf der PHP Seite zu einer Abstraktionsebene. Ja nicht mal ein Hinweis, dass man escapen sollte :(

Aber prepared Statements sind eh cooler, also:
Nunja. Dafuer brauchst du ein DBMS, was das kann.

Das ist also weder ein Argument für Python, noch gegen PHP ;) Gut funktionierende Abstraktionen liefern die meisten Sprachen inzwischen, man muss sie nur benutzen.
Eben. Und mein Argument ist, dass man sich in, meinetwegen, Python die Freiheit schlechten Code zu schreiben, erstmal erkaempfen muss.
Nicht mal die vorzeige Softwareschreiber benutzen eine Art Abstraktion.

Man brauch sich ja auch nur umschauen: Saemtilche Webapps
sind gelinde gesagt, scheisse.
Ich kenne bisher nur eine verwundbare Python Applikation.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-06-07 08:44
Anonymer User
Ich kenne bisher nur eine verwundbare Python Applikation.

Ist klar!
Du musst ja auch mal die Anzahl der Pythonprojekte in Relation zu den PHP-Projekten sehen…

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-06-07 14:56
Anonymer LEIFer
Ist klar!
Du musst ja auch mal die Anzahl der Pythonprojekte in Relation zu den PHP-Projekten sehen…
Stimmt, wenn man die betrachtet, dann wird einem eins klar: Man sollte in PHP noch viel mehr darauf achten, Leute zu sicherer Programmierung zu motivieren.

RE: PHP & MySQL, frage zum UPDATE Befehl 2007-06-07 15:11
TriPhoenix
Solange wie der offizielle Weg, eine Datenbankverbindung ueber die einzelnen Funktionen, ohne Abstaktion
Ja, das wäre natürlich schön, wenn es in der Standarddistribution schon mit drin wäre.

und vernuenftigem Escaping
Und was ist mit mysql_real_escape?

nunja, ich waere eher schockiert gewesen, wenn sowas ueberhaupt nicht moeglich waere. Aber s.o.: Der Programmierer wird fast provoziert, die schlechten PHP Stammfunktionen zu nehmen. Es gibt nicht mal einen bloeden Hinweis auf der PHP Seite zu einer Abstraktionsebene.
Naja, die ist in der Distribution halt nicht drin. Im C-Standard will ich ich nicht lesen, welche Erweiterungen hier und da noch erfunden sind ;) Klar, ein Hinweis ist immer nett, aber man kann meiner Meinung nach keinen Vorwurf draus machen, wenn es nicht gemacht wird.

Ja nicht mal ein Hinweis, dass man escapen sollte :(
Ein expliziter Hinweis da wäre nett, ist aber nicht wirklich zwingend dort. Die Beispiele benutzen dafür aber schon Escaping, veranschaulichen dem abschriebenden Anfänger gleich wie man das zu benutzen hat. Und wenn man dann guckt, was mysql_real_escape ist, sieht man auch gleich dort: "This function must always (with few exceptions) be used to make data safe before sending a query to MySQL.".

Aber prepared Statements sind eh cooler, also:
Nunja. Dafuer brauchst du ein DBMS, was das kann.
Oder eine Abstraktionsebene, die das macht.

Eben. Und mein Argument ist, dass man sich in, meinetwegen, Python die Freiheit schlechten Code zu schreiben, erstmal erkaempfen muss.
Das glaube ich garnicht unbedingt. Ja, du hast die Prepared-Statements (bzw. ähnlich implizites Escaping) gleich dabei. Ich glaube trotzdem dass mehr als genug Anfänger sowas wie
name = "John db.cursor.execute("SELECT name, nummer FROM phonebook WHERE name = '"+name+"') schreiben. Und das war jetzt nicht mit wirklich viel Kampf.

Nicht mal die vorzeige Softwareschreiber benutzen eine Art Abstraktion.
Seit dem 15.05.2007 gibt es sogar eine Klasse db_mysql_connector (Commsy 5.2.3) ;) Die ist allerdings (noch?) ziemlich klein und macht leider auch kein Escaping o.ä. [28] Aber vielleicht wird das ja noch was ;)

Ich kenne bisher nur eine verwundbare Python Applikation.
Ich kenne keine. Aber das liegt nunmal daran dass ich auch nicht wirklich Python-Webapplikationen kenne. Wie mein anonymer Vorsprecher schon sagte, es gibt wesentlich mehr PHP-Anwendungen. PHP kriegst du auf jedem Webserver nachgeschmissen und damit wird sich jeder (mehr oder weniger der Sicherheitsprobleme bewusste) Programmieranfänger am ehesten auf PHP stürzen und da ne Menge Fehler machen. Wenn man mit Webanwendungen anfängt, ist in PHP arbeiten nunmal massiv einfacher als Python, weil die Webserver das eben am schnellsten mitbringen.
Das Codequalitätargument ist damit (meiner Meinung nach) hier gleichzusetzen mit der Argumentation dass Unixe sicherer gegen Viren sind, weil man sowenige Unixviren oder gar Epidemien sieht. Das ist ne einfache Verbreitungssache, wäre Python zuerst gekommen und hätte heute jeder Webhoster Python, sähe der Python-Code weltweit gesehen nicht besser aus als der PHP-Code heute.