Snippets - Diskussionsthread

Ist das Snippet denn richtig angepasst?

PHP:
db_query("UPDATE %s SET %s='%s',%s='%s',%s='%s'",user,mail,'$mail',vname,'$vname',nname,'$nname');

1. %s = Tabellenname
2. %s = Tabellenspalte mail
3. %s = Wert von 2.
4. %s = Tabellenspalte vname
5. %s = Wert von 4.
6. %s = Tabellenspalte nname
7. %s = Wert von 6.

Naja ich hab die tabellenspaltennamen direkt drinnen und nur die variablen hinten stehend.
 
Also das Statment ist:
UPDATE user SET mail='test@test',vname='max',nname='muster' WHERE uid='1'

Aber in der DB steht nichts drin :wall:

mit einen normalen mysql_query = (... funktionierts
LG
 
uid ist doch sicher ein Int feld oder?
Also wieso '1'??
einfach uid=1

@phx, bei den Parameter hast du aber denke die '' vertauscht

falsch:
user,mail,'$mail',vname,'$vname',nname,'$nname'

richtig:
'user','mail',$mail,'vname',$vname,'nname',$nname


Aber wozu eigentlich die Spatennamen extra noch als Parameter übergeben ich fnde das wird sehr unleserlich, so meine meinung. Da erkennt man an der Abfrage selber gar nicht mehr was passiert...
 
Also den Einsatz von Snippet #32 sollte man nochmal überdenken, einfach mal über alls nen Escaping drüberzuhauen ist die wahrscheinlich dämlichste Lösung die man machen kann, einfach mal mit der Holzhammer-Methode alles escapen, also mit Sicherheit hat das nicht viel zu tun.
Das sieht mir mehr nach nem Flicken aus, das man keine Ahnung hat, wie man die Anwendung richtig absichert und escaped daher einfach mal alles.

Da wir alle Variablen damit escapen bin ich mir sicher es wird an diversen Stellen Probleme geben, wenn wir mal auf Input zugreifen müssen der dadurch doppelt escaped wird.
Dank magic_quotes und diesem "super" Fix, wird dann ein String "O'Reilly" zu "O\\\'Reilly", also der würde sicher von meiner Anwendung als Malicious Input deklariert werden, und somit gar nicht bis zum SQL durchkommen.
 
Es ist vielleicht die kürzeste und effektivste Methode aber meiner Meinung nach sicherlich nicht die dümmste. Warum ist es dumm vorsorglich alle Inputs zu escapen?

Ich hab dann mal ein stripslashes() rein getetan, damit sollte dein Problem gelöst sein..
 
Grad beim stöbern ist mir folgendes Posting aufgefallen:

* LIMIT 1 *
an jeden sicheren query gehört ein LIMIT. ganz egal, ob man etwas limitieren möchten, oder auch nicht. das hat nicht nur logische gründe, die sich auf den aufbau eines query beziehen, sondern auch rein praktische.

beispiel: irgendein hacker hat es vielleicht geschafft eure sql-anweisung aus einer seite zu injecten und schafft es damit, folgenden query zu erzeugen (hackerinjection ist fett):

DELETE * FROM user WHERE userID=123456 or userID>0

[...]

mit einer LIMIT-anweisung wäre so etwas nicht passiert:

DELETE * FROM user WHERE userID=123456 or userID>0 LIMIT 1

damit wäre der schlimmste der fälle nicht auf die gesamte tabelle angewendet worden, sondern nur auf einen einzigen datensatz beschränkt.

Die Begründung mit dem Hacker ist doch voll fürn Eimer, was ist denn wenn ich folgendes mache:

Code:
DELETE * FROM user WHERE userID=123456 [B][U]or userID>0[/U] --[/B] LIMIT 1
Das Limit ist in dem Fall ein Kommentar und wird nicht mehr beachtet, ergo würde doch wieder alles gelöscht :-?. Weiß jetzt nicht ob es schon einmal angesprochen wurde, aber da es so immer noch drin steht geh ich nicht davon aus :p

*edit*
Das Sternchen ist doch auch überflüssig :think:

*edit2*
Mist wurde schon erwähnt aber wollt ihr das nicht rausmachen? Ist ja im Prinzip falsch :p
 
Zuletzt bearbeitet:
Sicher ist es doch nur, wenn man ein Query immer auf bestimmte Dinge vor deren Ausführung prüft.
Sei es nötige Escapes zu haben, den SQL Konformen Standard einzuhalten, bestimmte Zeichen nicht zu zulassen, mögliche Zeichensatz Codierungskompatibilität beizubehalten, ...
Ein LIMIT wird als "eigensinniger" Standard bei dem PHP Produkt phpMyAdmin witziger Weise immer angehangen. Fragt doch die Entwickler, warum!

LIMIT v[,b] (v=von , b=bis)

LIMIT hat eigentlich nur einen sinnvollen Einsatz :
Man begrenzt damit die Datensätze und kann gleichzeitig eine Art "Positionsmarke" setzen, um halt eine geregelte Datensatzanzahl aus einer Gesamtdatenmenge zu "extrahieren"...

Nichts weiter
 
Ein LIMIT wird als "eigensinniger" Standard bei dem PHP Produkt phpMyAdmin witziger Weise immer angehangen. Fragt doch die Entwickler, warum!
Ich bin zwar kein PMA-Entwickler, aber die Frage kann dir selbst ich beantworten:
Mach mal n SELECT ohne LIMIT auf ne Tabelle, die mehrere Tausend Datensätze hat. Da hat der Server gewaltig zu arbeiten, du baust ne Latte Traffic und effektiv wartest du mehrere Minuten, bis du mit deiner DSL-Leitung das ganze Markup runtergeladen hast.

phpMyAdmin setzt daher per default (kannst du selber konfigurieren) n LIMIT, um den Tabelleninhalt immer nur seitenweise anzuzeigen und dich vor obigen Probleme zu schützen.
 
Danke theHacker, für diesen ( ich nenns mal ) Trivialfall. Ohne ein Limit in diesem Fall ist es so.
Aber die Entwickler setzen selbst dann ein Limit ran, wenn man eine eindeutige Selektion in der Abfrage schon drin hat. In meinen Augen überflüssig!
Wenn das Query eine Ergebnismenge === 1 hat, was die Entwickler aber nicht abschätzen können, weil sonst müsste vor dem Ausführen der Query die Struktur der Tabelle überprüft werden (Index, Unique Werte), um die sinnvolle Nutzung von Limit auch zu gewährleisten...
Ist bei dem Produkt aber nicht möglich, oder eher generell, weil die Ausführungszeiten einer Abfrage dann nicht mehr im Millisekundenbrereich liegen, sondern weit darüber.

Aber danke für die tolle Antwort theHacker
 
tobomator, verstehe ich das richtig, dass du dich darüber beklagst, dass phpMyAdmin automatisch LIMITs setzt? :roll:

Es ist natürlich manchmal nervig, wenn man bei seinen 39 Datensätzen diese auf zwei Seiten bekommt.. Aber besser 30 Datensätze pro Seite als gar keine Beschränkung und eventuell 100.000 oder noch mehr auf eine Seite... Da muss ich theHacker eindeutig zustimmen.

Deinen zweiten Post kann ich irgendwie nicht so ganz nachvollziehen / den verstehe ich nicht so wirklich ;)
 
Nein ich beschwere mich nicht darüber, wenn es sinnvoll ist, bei mehr Datensätzen als eine Seite visuell darzustellen in der Lage ist, aber bei folgendem ist es sinnlos:

SELECT * FROM 'user' WHERE `uid`='1'

hängt phpmyadmin ein LIMIT 1 an

Würde beachtet, das uid eventuell Unique ist oder ein Index, dann sind bestimmte Verhalten dran geknüpft. Somit wäre das Limit für mich unnütz.
 
aber bei folgendem ist es sinnlos:

SELECT * FROM 'user' WHERE `uid`='1'

hängt phpmyadmin ein LIMIT 1 an

Würde beachtet, das uid eventuell Unique ist oder ein Index, dann sind bestimmte Verhalten dran geknüpft. Somit wäre das Limit für mich unnütz.

Okay, wenn man genau die Abfrage so eingibt (wobei diese NICHT funktionieren würde, achte auf deine Hochkommatas :p) ist es nicht gerade nötig.

Wenn man von phpMyAdmin aber mal wegschaut fänd ich ein LIMIT 1 hinter der Abfrage wieder praktisch, wenn diese nicht statisch ist... (Schutzmechanismus.. Injections oder so)
 
Ich hab mir eben eine Kleine Funktion geschrieben die Mehrdimensionale Arrays in eine Datenbank eintragen kann.

Ich würde gerne mal eure Meinung dazu hören.

$array ist das Array das eingefügt werden soll in der Form
0|
key1|value1
key2|value2
key3|value3
1|
key2|value2
key4|value4
key3|value3
... | ...
$table ist die Tabelle in die das Array eingetragen werden soll

$append ist ein array mit Daten die an jede Zeile angehängt werden

Wenn $update true ist wird an den Query ein ON DUPLICATE KEY UPDATE hinzugefügt

Wenn $update true ist ist $keys ein array mit den Schlüsseln der Datenbank
PHP:
<?php
function insertArray($array, $table, $append=array(), $update=false, $keys=array()){        
        $arrkeys=array();
        foreach($array as $values)$arrkeys=array_merge($arrkeys, array_keys($values));
        if(!empty($append)) $arrkeys=array_merge($arrkeys, array_keys($append));
        $arrkeys=array_unique($arrkeys);
        $query="INSERT INTO ".$table."(".implode($arrkeys, ", ").") VALUES";        
        foreach($array as $data){
            $data=array_merge($data, $append);
            $temp2=array();
            foreach($arrkeys as $key){
                if(!is_numeric($data[$key]))$temp2[]="'".mysql_real_escape_string($data[$key])."'";
                else $temp2[]=$data[$key];
            }
            $row[]="(".implode($temp2, ", ").")";
        }
        $query.=implode($row, ",\n");
        if($update){
            $query.="ON DUPLICATE KEY UPDATE ";
            foreach($arrkeys as $key){
                if(!in_array($key, $keys)) $col[]=$key."=VALUES(".$key.")";
            }
            $query.=implode($col, ", ");
        }
        return mysql_query($query);
}?>
 
Zuletzt bearbeitet:
Wenn ich ein Mehrdimensionales Array in die DB speichern will, dann würde ich dafür Json dafür nehmen.
 
Es geht darum die Daten aus dem Array zu speichern.

um nur das Array zu speichern würde ich auch json bzw serialize etc benutzen.

Um mal meinen Anwendungsfall genauer zu beschreiben ich erzeuge mit einer anderen Funktion mehrere Datensätze mit Informationen diese Informationen sollen alle in der Datenbank gespeichert werden um jetzt bei 100 Datensätzen nicht 100 Querys zu brauchen nutze ich diese Funktion um das alles in 1 Query abzuhandeln.
 
Erstmal hab ich auf die schnelle das Gefühl, dass deine Funktion viel zu kompliziert ist.

  • Bspw. verstehe ich nicht, warum du ganz am Anfang ein array_merge mit einem leeren Array durchführst.
  • Die Abfrage !is_null() ist nicht logisch, du solltest eher !empty() prüfen. is_null() gibt nur true zurück, wenn der Ausdruck explizit "null" ist.
  • Das sort() macht auch Sinn, als dass es MySQL ziemlich egal ist ob es alphanumerisch sortiert ist oder nach dem System des 25ten römischen Kaisers durcheinander gebracht wurde
  • Meiner Meinung nach fehlen dir ein paar Leerzeichen zwischen den Ausdrücken, kann aber sein, dass das irrelevant ist weil die Trennung anders doch auch funktioniert
  • Welchen Sinn hat $var = "".$fobar
  • Was soll dein on Duplicate Key? Falls schon vorhanden, setzte den Wert der Spalte = dem Wert der Spalte? Etwas nicht zu ändern kann man auch einfacher erreichen..
  • Deine Formatierung ist schlecht, und meiner Meinung nach nur grausam lesbar

So, mein Senf dazu.. kann sein, dass da was dran falsch ist, aber ich blick nicht ganz durch bei der Funktion. Kommentare sind btw. was feines.
 
Erstmal danke für deine Meinung. So jetzt zu deinen einzelnen Punkten

  • Bspw. verstehe ich nicht, warum du ganz am Anfang ein array_merge mit einem leeren Array durchführst.
Weil array_merge seit PHP5 nurnoch arrays als argumente akzeptiert

  • Die Abfrage !is_null() ist nicht logisch, du solltest eher !empty() prüfen. is_null() gibt nur true zurück, wenn der Ausdruck explizit "null" ist.
Hast Recht hab es geändert danke.

  • Das sort() macht auch Sinn, als dass es MySQL ziemlich egal ist ob es alphanumerisch sortiert ist oder nach dem System des 25ten römischen Kaisers durcheinander gebracht wurde

Und auch hier das war noch ein überrest meiner debug Ausgaben.

  • Welchen Sinn hat $var = "".$fobar
Ist auch raus

  • Was soll dein on Duplicate Key? Falls schon vorhanden, setzte den Wert der Spalte = dem Wert der Spalte? Etwas nicht zu ändern kann man auch einfacher erreichen.

Es aktueliesiert einen Eintrag wenn es den Schlüssel schon einmal in der Tabelle gibt. (Doku) Wenn du es einfacher hinbekommst ein Array aus dem 17 von 100 Schlüsseln bereits in der Datenbank sind zu ändern und die anderen einzufügen immer her damit.

  • Deine Formatierung ist schlecht, und meiner Meinung nach nur grausam lesbar

Sieht in meinem Editor mit Syntax Highlighting deutlich übersichtlicher aus. Zu der Sache mit den Kommentaren ja stimmt die könnte ich noch hinzufügen.