MySQL Syntax mit POST und SESSION Variablen
Dirk
- php
2 Sven Rautenberg0 Tom0 Korrektur
Tom0 Dirk
0 Matty
Hallo zusammen,
ich bin auf einen neuen Server gezogen und der frisst leider meine alte Syntax nicht mehr und liefert mir nen Parse Error:
$sql = "INSERT INTO tabelle (indizierung, name, datum) VALUES ('$indizierung',$_SESSION['name'],$S_POST['datum'])";
Nun ist mir klar, dass ich den String von Hand mit '.' und Stringverknüpfungen manuell knüpfen kann, meine Frage ist aber, ob es einen anderen Weg gibt, die ' zu umgehen, da die Abfrage in Wirklichkeit viel länger ist und ich ne Menge von ihnen habe...
viele Grüße,
Dirk
Moin!
ich bin auf einen neuen Server gezogen und der frisst leider meine alte Syntax nicht mehr und liefert mir nen Parse Error:
$sql = "INSERT INTO tabelle (indizierung, name, datum) VALUES ('$indizierung',$_SESSION['name'],$S_POST['datum'])";
Nun ist mir klar, dass ich den String von Hand mit '.' und Stringverknüpfungen manuell knüpfen kann, meine Frage ist aber, ob es einen anderen Weg gibt, die ' zu umgehen, da die Abfrage in Wirklichkeit viel länger ist und ich ne Menge von ihnen habe...
Du mußt sowieso Escaping vornehmen mit mysql_real_escape_string(), der Funktionsaufruf ist aber nicht innerhalb von Strings kapselbar.
Auswege:
sprintf() - da kannst du Variablen und Stringzusammensetzung nett trennen.
mysqli (anstelle von mysql) mit Prepared Statements - dasselbe Verfahren, nur mit automatischem Escaping.
Ansonsten: Passende Funktion bzw. Methode bauen, die den Vorgang im Grundsatz vereinfacht.
- Sven Rautenberg
Hello,
$sql = "INSERT INTO tabelle (indizierung, name, datum) VALUES ('$indizierung',$_SESSION['name'],$S_POST['datum'])";
Nun ist mir klar, dass ich den String von Hand mit '.' und Stringverknüpfungen manuell knüpfen kann, meine Frage ist aber, ob es einen anderen Weg gibt, die ' zu umgehen, da die Abfrage in Wirklichkeit viel länger ist und ich ne Menge von ihnen habe...
Es wird Dir nichts anderes übrig bleiben, als alles neu zu coden, denn ertens müssen Strings in Häkchen übergeben werden und zweitens hast Du kein Escaping vorgesehen.
Es kann Dir also jeder über die Post-Parameter Deine Datenbank kaputt machen.
Bau Dir ein Values-Array auf:
$_values['feldname1'] = mysql_resq($_SESSION['irgendwas']);
$_values['feldname2'] = mysql_resq($_POST['feldname2']);
Die Funktion mysql_resq() ist selbst erfunden, vereinfacht aber die Schreibarbeit
##-----------------------------------------------------------------------------
##-----------------------------------------------------------------------------
function mysql_resq($value, $connection, $quote="'")
{
return $quote . mysql_real_escape_string($value, $connection) . $quote;
}
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
function mysql_make_insert_string($_values, $table, $connection);
{
$insert_string = false;
if(!is_array($_values)) return $_insert_string;
if /count($_values) > 0)
{
$sql = "insert into $table ". implode("
,",array\_keys($\_values))."
".
" values (".
implode($_values).")";
}
return $insert_string;
}
Die zweite Funktion baut Dir dann den ersten teil Deines Insert-Strings zusammen.
Wenn Spalten dazwischen sind, die mit NULL osder FALSE belegt werden müssen, darft Du den Feldwert innerhaltb des Strings natürlich nicht in Häkchen einpacken.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hello,
#-----------------------------------------------------------------------------
combine the mysql insert string
#-----------------------------------------------------------------------------
function mysql_make_insert_string($_values, $table, $connection);
{
$sql = false;
if(!is_array($_values)) return $sql;
if (count($_values) > 0)
{
$sql = "insert into$table
". implode("
,",array\_keys($\_values))."
".
" values (".
implode($_values).")";}
return $sql;
}
So sollte sie schon etwas besser funktionieren
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Hallo,
danke Euch schonmal. Habe gehofft, es geht auch einfacher. Die Funktion von Tom ist klar, aber eine Frage habe ich zu mysqli - muss ich dann kein mysql_real_escape_string mehr machen? Kann mir das jemand kurz erklären?
viele Grüße, Dirk
Hello,
[...] aber eine Frage habe ich zu mysqli - muss ich dann kein mysql_real_escape_string mehr machen? Kann mir das jemand kurz erklären?
Sieh Dir mal http://de3.php.net/manual/de/function.mysqli-prepare.php an.
Ich find's zu kompliziert.
Erinnert mich irgendwie an die rudimentäre Zeit von bTrieve/scalable
Aber vermutlich habe ich den Sinn darin nur noch nicht verstanden.
Im Zusammenspiel mit einer Hochsprache, wie C oder Pascal könnte ich mir vorstellen, dass es Vorteile gibt, aber mit PHP?
Das "Escaping" findet eigentlich nur an einer vorgezogenen Stelle statt, weil keine Daten mehr über eine Textschnittstelle übergeben werden, sondern Variablen über die Bind-Funktion.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
echo $begrüßung;
[...] aber eine Frage habe ich zu mysqli - muss ich dann kein mysql_real_escape_string mehr machen? Kann mir das jemand kurz erklären?
Sieh Dir mal http://de3.php.net/manual/de/function.mysqli-prepare.php an.
Um das Kind nochmal beim Namen zu nennen: Das Stichwort heißt Prepared Statements.
Das "Escaping" findet eigentlich nur an einer vorgezogenen Stelle statt, weil keine Daten mehr über eine Textschnittstelle übergeben werden, sondern Variablen über die Bind-Funktion.
Es mag einige Datenbank-Abstraktionsschichten geben, die Prepared Statements simulieren, aber mysqli gehört nicht zu diesen. Wenn die Prepared Statements unter mysqli genutzt werden, geht zuerst ein SQL-Statement mit Platzhaltern drin auf die Reise zu MySQL. Die Werte für die Platzhalter gehen anschließend auf eigenem Weg zum MySQL-Server.
Die Werte werden bei P.S. nicht in einen Befehlstext eingebunden. Es müssen keine Begrenzungszeichen gesetzt werden, um Befehl von Nutzdaten zu unterscheiden. Und es müssen auch keine mitten im Wert vorkommenden Begrenzungszeichen und andere für die Textschnittstelle ungünstige Zeichen für diese Texteinbindung behandelt werden. Deswegen fällt hier das Maskieren und Escapen weg.
Ich find's zu kompliziert.
Da stimme ich dir zu. Mir persönlich gefällt daran nicht, dass sowohl auf dem Hinweg als auch auf dem Rückweg einzelne Variablen an das $stmt (also das was mysqli_prepare() zurückliefert) gebunden werden müssen. Man kann nicht einfach ein Array mit Werten hingeben, nein, einzelne Variablen müssen es sein. Besonders beim Ergebnis ist das recht umständlich, weil ein Datensatz nun nicht mehr gebündelt vorliegt. Da ich trotzdem die Daten im Array übergeben und entgegennehmen möchte, muss ich hier mit call_user_func_array() rumhantieren. (Nein, nicht jedes Mal wieder neu. Das ist in meiner persönlichen Datenbankabstraktionsschicht implementiert.)
Dass das so [...] implementiert ist, ist der MySQL-API geschuldet, da ist das ebenfalls so kompliziert.
Bei PDO ist das deutlich benutzerfreundlicher gelöst. Allerdings werden die P.S. vom MySQL-PDO-Treiber nur simuliert statt direkt über die MySQL-API ausgeführt zu werden. (Zumindest war das bei meiner letzten Beobachtung so, die aber einge Zeit zurückliegt.)
echo "$verabschiedung $name";
Hello,
Da stimme ich dir zu. Mir persönlich gefällt daran nicht, dass sowohl auf dem Hinweg als auch auf dem Rückweg einzelne Variablen an das $stmt (also das was mysqli_prepare() zurückliefert) gebunden werden müssen. Man kann nicht einfach ein Array mit Werten hingeben,[...]
Da wäre es selbst bequemer, wenn man einen Blockbuffer mit den Werten mittels pack() vorbereiten müsste. Im Prinzip macht die Schnittstelle ja bei prepared Statements oswas ähnliches, denn die Typen will sie ja haben.
Ich sehe noch nicht die Vorteile gegenüber der Interpreter-Version, also der "normalen" Textschnittstelle. Ist das Arbeiten mit prapared Statements performanter auf der Datenbankseite?
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
echo $begrüßung;
Da stimme ich dir zu. Mir persönlich gefällt daran nicht, dass sowohl auf dem Hinweg als auch auf dem Rückweg einzelne Variablen an das $stmt (also das was mysqli_prepare() zurückliefert) gebunden werden müssen. Man kann nicht einfach ein Array mit Werten hingeben,[...]
Da wäre es selbst bequemer, wenn man einen Blockbuffer mit den Werten mittels pack() vorbereiten müsste. Im Prinzip macht die Schnittstelle ja bei prepared Statements oswas ähnliches, denn die Typen will sie ja haben.
str_repeat('s', count($params)) für den types-Parameter tut es auch. MySQL nimmt es ja nicht übel, wenn man Zahlen als String übergibt, auch bei P.S. nicht. Auch für NULL braucht es keine Spezialbehandlung. Es gibt keinen speziellen Typ-Buchstaben. Wenn die Variable ein PHP-NULL enthält, landet ein DB-NULL im Feld.
Ich sehe noch nicht die Vorteile gegenüber der Interpreter-Version, also der "normalen" Textschnittstelle. Ist das Arbeiten mit prapared Statements performanter auf der Datenbankseite?
Es ist einfach bequemer, ein Statement mit Platzhaltern zu notieren und dann dieses zusammen mit einem Array voll Daten an eine Funktion zu geben, die sich um das Datenbankhandling kümmert. Kein Zusammensetzen des Statements aus mehreren Teilstrings, kein Maskieren und Escapen von Werten. Über Performance mach ich mir keine Gedanken, solange sich eine Anwendung performant anfühlt. Ich muss kein in Massen anstürmendes Publikum bedienen.
echo "$verabschiedung $name";
Hallö,
*lacht* ihr seid ja ziemlich fachspezifisch. Ich komm nicht ganz mit. Sehe ich das richtig: ich muss wenn ich meine normale mysql Verbindung aufbaue, mysql_realescape_string verwenden, wenn ich mysqli verwenden will, muss ich auch alle anderen Befehle mit dein i Funktionen machen - z.B. connect usw. ?
Sorry, ist vielleicht ne dumme Frage, aber ich habe damals mit PHP 4 gelernt und da gab es sowas alles nicht und es hat trotzdem prima funktioniert...
viele Grüße,
der Dirk
Hello,
*lacht* ihr seid ja ziemlich fachspezifisch. Ich komm nicht ganz mit. Sehe ich das richtig: ich muss wenn ich meine normale mysql Verbindung aufbaue, mysql_real_escape_string() verwenden, wenn ich mysqli verwenden will, muss ich auch alle anderen Befehle mit dein i Funktionen machen - z.B. connect usw. ?
Ja, das ist so.
Es ist eine eigene Bibliothek, die an einigen Stellen etwas leistungsfähiger sind.
Ob man das aber wirklich braucht?
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Moin!
*lacht* ihr seid ja ziemlich fachspezifisch. Ich komm nicht ganz mit. Sehe ich das richtig: ich muss wenn ich meine normale mysql Verbindung aufbaue, mysql_real_escape_string() verwenden, wenn ich mysqli verwenden will, muss ich auch alle anderen Befehle mit dein i Funktionen machen - z.B. connect usw. ?
Ja, das ist so.
Es ist eine eigene Bibliothek, die an einigen Stellen etwas leistungsfähiger sind.
Ob man das aber wirklich braucht?
Ja, das braucht man.
Erstens: mysqli kann exakt das, was mysql kann. Es ist also kein Neulernen erforderlich, man kann einfach ein "i" anhängen.
Zweitens: mysqli kann auch objektorientiert, was mysql nicht kann. Damit spart man sich das idiotische Reimplementieren der DB-Funktionen in Klassen, man erweitert die mysqli-Klasse allenfalls. Aus Sicht der Objektorientierung ist mysqli ein deutlich arbeitserleichternder Fortschritt.
Drittens: Nur mit mysqli sind die neueren Features in MySQL zu nutzen, z.b. Prepared Statements oder Stored Procedures.
- Sven Rautenberg
Hello,
Drittens: Nur mit mysqli sind die neueren Features in MySQL zu nutzen, z.b. Prepared Statements oder Stored Procedures.
Prepared Statements mag ich nicht :-)
Der Nutzen hat sich mir noch nicht wirklich erschlossen, aber das kommt vielleicht noch.
Aber wie Du das mit den Stored Procedures meinst, ist mir nicht klar.
Ein mysql_call() konnte ich nicht finden.
Einen SP-Call mittels Query-Statement kann man doch über die normalen mysql_* Funktionen auch schon nutzen?
Wenn ich richtig gezählt habe, sind 79 Funktionen zuzüglich der Objektinitialisierung durch mysqli() hinzugekommen. Dafür sind 16 Funktionen weggefallen.
Ob man die hinzugekommenen nun wirklich alle braucht, bezweifele ich eben.
Viele der Funktionalitäten lassen sich auch durch ein "normales Query" erreichen.
Ist es soviel günstiger, für spezielle Queries eine eigene Funktion zu haben?
Hat schon mal jemand verglichen? Wieviel mehr Hauptspeicher kostet diese Umsetzung allgemein und wieviel klaut es meinem Script, wenn ich in ein Datanbankobjekt erzeuge?
Das muss ich gleich mal ausprobieren, aber mein Server streikt schon wieder :-(
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Moin!
Drittens: Nur mit mysqli sind die neueren Features in MySQL zu nutzen, z.b. Prepared Statements oder Stored Procedures.
Prepared Statements mag ich nicht :-)
Macht ja nichts.
Der Nutzen hat sich mir noch nicht wirklich erschlossen, aber das kommt vielleicht noch.
Performance dürfte das einzige gültige Argument sein. Wenn du eine lange Liste von Werten in die DB schreiben willst, dann bietet sich ein INSERT an, dass man als prepared statement nutzt, und dem dann nur noch die Massendaten nachliefert. Senkt erheblich Parsing-Zeit in der Datenbank.
Aber wie Du das mit den Stored Procedures meinst, ist mir nicht klar.
Wenn man eine Stored Procedure in die Datenbank tun will, kann dies nur über mysqli_multi_query() geschehen, da mysqli_query() und mysql_query() beim Auftreten des ersten Semikolons im String abschneiden.
Ein mysql_call() konnte ich nicht finden.
Einen SP-Call mittels Query-Statement kann man doch über die normalen mysql_* Funktionen auch schon nutzen?
Hab ich noch nie gemacht, die Doku von MySQL deutet aber darauf hin, dass ein Query mit "CALL" eventuell ein multiples Ergebnis zurückgibt bzw. zurückgeben könnte, weshalb der Query allein schon mit mysqli_multi_query() ausgeführt werden sollte.
Wenn ich richtig gezählt habe, sind 79 Funktionen zuzüglich der Objektinitialisierung durch mysqli() hinzugekommen. Dafür sind 16 Funktionen weggefallen.
Ob man die hinzugekommenen nun wirklich alle braucht, bezweifele ich eben.
Würde man sie nicht brauchen, wären sie nicht hinzugefügt worden.
Viele der Funktionalitäten lassen sich auch durch ein "normales Query" erreichen.
Ist es soviel günstiger, für spezielle Queries eine eigene Funktion zu haben?
Beispiel?
- Sven Rautenberg
Hello,
Aber wie Du das mit den Stored Procedures meinst, ist mir nicht klar.
Wenn man eine Stored Procedure in die Datenbank tun will, kann dies nur über mysqli_multi_query() geschehen, da mysqli_query() und mysql_query() beim Auftreten des ersten Semikolons im String abschneiden.
Das könnte natürlich glatt so sein. Per PHP habe ich sie tatsächlich noch nie angelegt.
Der phpMyAdmin kann (konnte?) es ja auch nicht.
Ich habe sie bisher immer über SQL-Front oder als das noch nicht wieder auf dem Markt war, über die mysql-Konsole erfasst. Macht man ja eigentlich auch nicht so oft, wenn sie vorher gut durchdacht worden sind.
Einen SP-Call mittels Query-Statement kann man doch über die normalen mysql_* Funktionen auch schon nutzen?
Hab ich noch nie gemacht, die Doku von MySQL deutet aber darauf hin, dass ein Query mit "CALL" eventuell ein multiples Ergebnis zurückgibt bzw. zurückgeben könnte, weshalb der Query allein schon mit mysqli_multi_query() ausgeführt werden sollte.
Muss ich mir nochmal genauer ansehen.
Der einfache Call hat bisher immer geklappt.
Aber ich habe das eben nochmal überprüft:
Ich habe mittels Strored Procedure einige (teilweise fest verdrahtete) Select-Statements laufen, die automatisch eine Historie schreiben, also quasi einen "on Select Trigger" nachbilden. Der Datenbankuser muss dabei keinerlei Rechte auf die Tabellen haben, das Execute-Recht für die SP reicht.
Das funktioniert mit mysql_query nicht. Da gibt es einen Fehler, dass der Rückgabewert nicht im Kontext abgeliefert werden kann. Mit mysqli_query klappt das dann.
Im Prinzip sieht es (gekürzt) so aus:
CREATE DEFINER=superuser
@%
PROCEDURE wgr\_select
()
COMMENT 'Warengruppen abfragen'
begin
insert into testserver.historie set qtype='select', uname=user();
select id_wgr, name from wgr;
end;
#-------------------
$sql = "call testserver.wgr_select()";
$res = mysqli_query($con, $sql);
if (mysqli_errno($con)> 0) die('Fehler beim Query '.mysqli_error($con));
Ich war letztens dabei abgestürzt, wei man die Statements in der SP bindet, wenn es notwendig ist.
Bei diesem ist es nicht unbedingt notwendig, weil ein zuu späte geschriebener Historie-Datensatz die Integrität nicht gefährdet, aber bei anderen PS ist es notwendig. An der Transaction innerhalb einer SP knabber ich noch.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
$sql = "INSERT INTO tabelle (indizierung, name, datum) VALUES ('$indizierung',$_SESSION['name'],$S_POST['datum'])";
Ist das kein Schreibfehler und sollte $_POST['datum'] heißen? ohne "S"?
Gruß
Matty