[PHP/MySQL+Sicherheit] Datenbankklasse, Validierung von Eingaben, etc.

sind zu wenige die hier was damit anfangen können, beziehungsweise wollen.
Fragen einfach hier stellen oder du weisst wohin :biggrin:
 
<ironie>
Hat MySQL nicht auch eine Art strict-Mode, oder täusch ich mich grad ... ? :roll:
Der Strict-Mode in MySQL ist genauso fürn Arsch, wie wenn man register_globals=off in der PHP-Config stehen hat :ugly:
</ironie>
[...] aber was haltet Ihr davon alles zu Zend_Db in einem weiteren Unterforum zu kapseln. Ich würde sagen das Zend ziehmlich angesagt ist und wenn sich noch mehrere wie ich da rein arbeiten ist es evtl sinnvoll.
Nee, kein Unterforum :nö: Die einzig sinnvolle Untergliederung, die man hier machen könnte wäre, Programmierung in "sinnvolle Fragen" und "hilhfe!!! ich wil eine losesite schreiben aber nihcts geht" aufzuteilen :ugly: :mrgreen:

Ein "[PHP/Zend]" im Threadtitel tut es auch. Bzw die Idee mit dem Thread ist eigentlich noch besser :)
 
Irgendwie kann ich dem in keinster Weise zustimmen :biggrin:

Eine ganze Menge Code-Overhead, Unübersichtlichkeit, die Gefahr, es zu vergessen. Schon mal daran gedacht?

Aber das hat mir meine Frage nicht beantwortet. Letzt endlich macht die Klasse ja das gleiche, was der Standard geschriebene Code auch ist!

Und wer Syntax unleserlich fände sollte noch Anfänger in der Programmierung sein!

Argumentation:

- Code-Overhead
- Unübersichtlichkeit

Was hälst denn davon:?

PHP:
<?
$result = mysql_query("
UPDATE `beispiel1`
SET
`spalte1` = '".mres( $_POST['1'] )."',
`spalte2` = '".mres( $_POST['2'] )."',
`spalte3` = '".mres( $_POST['3'] )."',
`spalte5` = '".mres( $_POST['4'] )."'
WHERE
`wert7`= '".mres( $_POST['7'] )."'
LIMIT 3,10
");

$res = mysql_queryf("UPDATE `beispiel1` SET `spalte1`= %u, `spalte2`= %u, `spalte3`= %u, `spalte4`= %u, `spalte5`= %u, WHERE `wert7`= %u  LIMIT 3, 10",$_POST['1'],$_POST['2'],$_POST['1'],$_POST['1'],$_POST['1']); 

$res = mysql_queryf("
UPDATE `beispiel1` 
SET 
`spalte1`= %u, 
`spalte2`= %u, 
`spalte3`= %u, 
`spalte4`= %u, 
`spalte5`= %u 
WHERE 
`wert7`= %u  
LIMIT 3, 10"
,$_POST['1']
,$_POST['2']
,$_POST['1']
,$_POST['1']
,$_POST['1']
); 
?>

Das Beispiel zeigt, Leserlichkeit eines Codes ist reine Sache der Schriftgestaltung. Ich finde die erste Methode die aller leserlichste mit dem Standardcode. Leserlichkeit hängt mit der Gestaltung von Buchstaben, Zeilen und Fläche direkt zusammen (Typografie) und ist eine Dimension im Rahmen der Lesbarkeit eines Textes.

Laut Wikipedia sind wichtige Faktoren für die Leserlichkeit:
* Schriftart, Auszeichnungsart und Schriftgrad
* Durchschuss (Zeilenabstand), Satzbreite (Zeilenlänge) und Zeilenfall (Block- oder Flattersatz)
* Materialien wie Farben und Untergrund wie Bildschirm, Papiersorte oder anderes Trägermaterial.

Im wesentlichen kann daher ein Funktion oder eine Klasse dieser Art die Leserlichkeit nicht wirklich verbessern. Die Gestaltung des Codes, und Werkzeuge die die Syntax highliten oder den Schriftgrad bestimmen jedoch schon!



Das Argument mit dem Vergessen, dass lass ich eventuell noch nachvollziehbar stehen. Wobei ich hier anmerken würde, dass dies ein grob fahrlässiger Fehler wäre!




Zu den Benchmark Sachen wollte ich noch etwas neutrales hinzufügen. Sicher sind die Sachen heute Moderner und weniger Leistungsaufwändig wie das Zeug von Gestern. Aber dennoch verbraucht eine Solche Klasse gegenüber einem einfach Query sicherlich um 300% mehr Leistung. Das zumindest nach meinen Messungen!

Wir brauchen heute meistens nicht wegen ein paar Ressourcen rum heulen . Da dies für eine normale HP meist nicht relevant ist. Aber dennoch bleibt dies ein Nachteil, weil diese Ressourcen auch tatsächlich verbraucht werden. JA heute hat man Ressourcen im Überschuss, aber nicht ohne Ende! Und je mehr Ressourcen beim Server übrig bleiben desto mehr kann er für andere Aufgaben außerhalb des interpretieren (z.B. die Datenbank) offen halten.



Ich will keinem seine Klassen ausreden. Aber wirkliche Vorteile ergeben sich dadurch denke ich nicht! Ich habe zumindest bis auf das (grobe Vergessen) kein Argument gehört, welchen Vorteil eine solche Klasse oder Funktion haben sollte, den ich auch noch gering nachvollziehen könnte!

Funktionen tragen schon dazu bei, vor allem die länge des Codes und die Wartungsmöglichkeit des Codes bedeutend zu verbessern. Aber auf diesen Fall trift das ja nicht zu, da diese Funktion, der Query und die Variablen eben so oft geschrieben werden müssen wie ohne einer solchen Klasse.

Der Aufwand bleibt immer der Gleiche! Beim Standardcode müsste man den Funktionsabruf, den Query, die Variablen und den Funktionsnamen (zum escapen) ständig ausschreiben. Und bei einer solchen Klasse könnte man sich einzig nur Funktionsnamen (zum escapen) sparen müsste aber dafür die markup (%u) einsetzen und die Variablen als Parameter gestalten. Schneller ist dieser Code über eine Klasse daher auch nicht geschrieben, noch wäre der in diesem Fall einfacher zu warten!



Einer der schlimmsten Nachteile in meinen Augen bleibt die Tatsache, dass man den Query verfälscht! (Man passt den Query Code an die Klasse an)! Dies ist für mich der gravierendste Nachteil!



Kann schon sein, dass wir da etwas verschiedener Meinungen sind. Das ist auch nicht schlimm.

Ich hab jetzt 3 Kontra gegeben und ein Pro gehört! Was zumindest in meinen Augen neutraler weise auch nachvollziehbar ist.

Ich bin der Typ Mensch der den Gedanken gerne auf den Grund geht. In tausenden Dingen finde ich Funktionen und Klassen sehr sinnvoll. Um einen Query von Injektion zu schützen, in dem man den Query und den Funktionsabruf ändert nicht.

Klar kann ich mir dafür eine Klasse oder ein Funktion schreiben. Aber ob diese wirklich Vorteile bringt bezweifle ich doch sehr! Ich komm einfach auf keinen Vorteil der sich daraus ergeben könnte (Bis auf die Sache mit der Vergesslichkeit). Aber einige Nachteile die das mit sich bringt! Sonst würde ich dem auch zustimmen!

Dazu fällt mir ein 2 Sprichworte ein:
Man sollte den Dingen auf den Grund sehen!
Gefahr erkannt, Gefahr gebannt.
So wird man erkennen was wirklich Sinn macht und sich zu helfen wissen!
 
Zuletzt bearbeitet:
Nunja, Du beziehst Deine Argumentation auf das reine Query. Eine vernünftige Datenbankklasse kann aber weit mehr als das. Alleine das ResultSet-Auslesen bietet Ansatzpunkte für eine Vielzahl von Funktionen. Das ResultSet komplett in ein Array umwandeln, um nur ein Beispiel zu nennen, ist etwas, was man nicht in einer Zeile hinkriegen kann und wenn man dies öfter verwendet, spart man sich eine Menge Arbeit (Stichwort Don't Repeat Yourself).

Funktionen umzubenennen (mysql_real_escape_string() -> mres()) ist doch auch nur Augenwischerei und dient in keinster Weise der Übersichtlichkeit (ausgegangen davon, dass nicht nur eine Person im Laufe der Zeit den Code verwaltet).

Das wichtigste Argument für OOP ist aber definitiv die Kapselung der Funktionalitäten. Erstelle ich mir meine DB-Klasse, habe ich ein Objekt, das alle Funktionen beinhaltet, mir darüber hinaus hilft, Standardabläufe zu vereinfachen und - was nicht verachtet werden sollte - das Ganze passiert in einem eigenen Namensraum.

Ein Beispiel noch für den wirklichen Nutzen von OOP: Du hast nun beispielsweise das Szenario mit dem "ResultSet in ein Array umwandeln". Einmal immer wieder per Hand und einmal per Klasse. Sprich: Im ersten Fall habe ich über den kompletten Code verteilt immer wieder die gleiche Methodik verwendet, um dies zu machen (Array erstellen, in einer Whileschleife füllen und abschliessend ResultSet freigeben). Im zweiten Fall habe ich dies mittels einer Methode realisiert, die die Funktionalität kapselt. Entdecke ich nun einen Fehler in diesem Ablauf, muss ich's im ersten Fall x-Mal ändern, im zweiten Fall hingegen ein einziges Mal in der Klasse.

Natürlich wirst Du argumentieren, dass Du das wiederum in einer Funktion kapseln kannst, aber wozu? Wozu sollte ich den globalen Namensraum mit unnötig vielen Funktionen vollknallen, die semantisch in einen eigenen Bereich gehören?

Zum Schluss noch das Totschlagargument: Was machst Du, wenn Du statt MySQL PostgreSQL, SQLite oder eine andere Datenbanksoftware verwendest willst/sollst/musst? In dem Fall kommt mit Deiner Variante eine Menge Arbeit auf Dich zu. Mit einer gut designten Klasse erweitert man diese einfach nur um die entsprechenden Methoden im anderen "Dialekt" und das war's.

Anschaulicher, um zu zeigen, was man mit Klassen auf einfachstem Wege realisieren kann:
PHP:
DBManager::SetConnection('db1', 'mysql://user:password@localhost/database');
DBManager::SetConnection('db2', 'oracle://user:password@otherhost/database');

$result_mysql = DBManager::Get('db1')->query("SELECT foo FROM bar WHERE id=?",
    $_GET['id']
)->to_array();
$result_oracle = DBManager::Get('db2')->query("SELECT useless, stuff FROM oracle_database WHERE overhead=?", 
    $_GET['a_lot']
)->to_array();
Ich denke, diese Funktionalität ohne eine entsprechende DB-Klasse ist wesentlich länger als dies und ob's dadurch besser lesbar ist, möchte ich bezweifeln. Zudem: Der Code oben kann durchaus in der Lage sein, die Verbindung zur DB erst dann aufzubauen, wenn sie benötigt wird. Kannst Du das mit Funktionen auch? ;)
 
Ich hätte auch noch was:
Vorweg. Meine Datenbank-Klasse kann nicht sonderlich viel - hab schon mal überlegt, sie neu und richtig zu schreiben, weil das meiste sind bei mir wirklich nur Funktionen und keine Spur von OOP. Das soll aber nur heißen, dass das folgende Argument auch auf Leute zutrifft, die nur eine mysql_queryf()-Funktion haben.

In meiner Klasse gibt es ein Flag, welches, wenn eingeschalten, den Debug-Modus aktiviert. Wird eine Query ausgeführt (ja, Overhead für die if-Abfrage des Flags, auch wenn deaktiviert - klar), so wird die Ausführungszeit der Abfrage gemessen und zusammen mit dem Querystring in einem Array abgespeichert, was man sich einfach mal eben mit print_r() ausgeben lässt.
Besonders hilfreich, um mehrfache Abfragen derselben Information und ineffiziente Queries aufzuspüren.

Was ich eigentlich sagen will: Wer mysql_query() (und mit mysql_real_escape_string() oder mres()-Abkürzung) benutzt, kann nicht erweitern. Muss wirklich mal was bei jeder Abfrage gemacht werden, so muss der Code an xhundert Stellen geändert werden.
...oder eben nur einmal in der Klasse.