2.3k Aufrufe
Gefragt in Skripte(PHP,ASP,Perl...) von
Hallo,

ich mache zur zeit größere Projekte und hab hierzu ein paar grundsätzliche Fragen:

1. Wenn ich globale Funktionen (in einer functions.php) habe, und diese Daten aus einer Datenbank benötigt, macht es dann mehr Sinn, die Datenbank-Abfrage in diese Funktion auszulagern oder sollte ich innerhalb der Funktion davon ausgehen, dass z.B. der Ressource-Identifier übergeben wird und evtl checken?

2. Sollte ich generell alle Datenbankabfragen am anfang des Skriptes machen und das Ergebnis in einem Array speichern? Oder sollte ich lieber "on-the-fly" das DB-Ergebnis auswerten?

3. Da es sich um größere Projekte handelt und ich viele Funktionen verwende, macht es dann Sinn, Parameter per Referenz zu übergeben, um die Geschwindigkeit zu erhöhen? Oder sollte man das generell gar nicht tun?

4. Datenbankabfragen: Wenn ich weiß, dass ich nur eine Ergebniszeile zurückgeliefert bekomme und auch nur auswerten will, ist es dann trotzdem nötig, mit einer while-Schleife und z.b. mysql_fetch_assoc() zu loopen? kann man das auch einfacher lösen?

5. Etwas spezieller: da mit mysql_query ja entweder ein ergebnis zurückkommt (u.U. auch mit 0 Zeilen), hab ich meist folgenden Code verwendet:

$res = mysql_query("SELECT *FROM table");
$rows = mysql_num_rows($res);

if ($res && $rows) {
while ($row = mysql_fetch_array($res)) {
// ....
}
}

Was sagt ihr dazu?

Wäre super, wenn ihr mir zu den Fragen tipps geben könntet und wie ihr sowas handhabt.

Gruß, Daniel

8 Antworten

0 Punkte
Beantwortet von son_quatsch Experte (5.3k Punkte)
1.) Die Daten innerhalb der Funktion zu ermitteln macht dann Sinn, wenn sie auch nur (ab) dort gebraucht werden. Wenn sie aber später oder früher bereits erfragt werden könnten, sollte für die Abfrage eine eigene Funktion existieren - das verhindert redundten Code.

2.) Nein! Das bringt PHP unnötig schnell an die Speichergrenzen. Das würde nur dann Sinn machen, wenn all diese ermittelten Daten auch tatsächlich verwertet werden - ansonsten in jedem Fall individuell.

3.) PHP sieht Parameterübergaben sogar standardmäßig als Referenz und erzeugt erst eine Kopie davon, wenn diese auch tatsächlich verändert werden. Da wird also schon viel unter der Haube optimiert. Aber wenn du die Daten eh nicht veränderst, kannst du sicherheitshalber auch explizit Referenzen übergeben.

4.) Weil die Ergebnismenge genausogut leer sein kann. Oder die Abfrage einen Fehler erzeugt. Beides kann man nie ausschließen. "Loopen" musst du es trotzdem nicht, aber dazu siehe Beispiel unter 5.

5.) Total unnötig, die Treffermenge abzufragen. Für jedes erdenkliche Szenario kann immer folgendes Konstrukt verwendet werden:


$sSql= "SELECT *
FROM tabelle";
$res1= mysql_query( $sSql ) or die( 'Fehler in: '. $sSql. ' (#'. mysql_errno(). ') '. mysql_error() );

$i1= 0;
while ( $a1= mysql_fetchrow( $res1 ) ) {
print_r( $a1 );
$i++;
}
print( $i1. ' Treffer insgesamt' );
mysql_freeresult( $res1 );
Die Zuweisung der Ergebniszeile ist gleichzeitig auch die Bedingung der While-Schleife, anscheinend ist das nicht klar. Wenn man 0-1 Ergebniszeilen erwartet, kann man also auch ohne While-Schleife auskommen - muss dann allerdings noch prüfen, ob überhaupt ein Ergebnis vorliegt:

$sSql= "SELECT *
FROM tabelle";
$res1= mysql_query( $sSql ) or die( 'Fehler in: '. $sSql. ' (#'. mysql_errno(). ') '. mysql_error() );

$a1= mysql_fetchrow( $res1 );
if ( !$a1 ) die( 'Kein Ergebnis!' );
mysql_freeresult( $res1 );

Das allerwichtigste sind aber Fehlerbehandlungen. Ich hab sie einfach mit die() gemacht, allerdings wäre eine eigene Funktion dafür wesentlich sinnvoller. In dieser kann man die Ausgabe einheitlich gestalten - und außerdem kann man ihr immer __LINE__ und __FILE__ übergeben - dann weiß man auch gleich wo in welchem Quelltext ein Fehler aufgetreten ist.
0 Punkte
Beantwortet von
Vielen Dank für die antwort, hat mir echt weitergeholfen.

zwei kleine fragen noch:

1. Muss man nur nach Select-Anweisungen ein mysql_free_result durchführen? bisher hab ichs immer ganz weggelassen, weil ich eh nur eine Datenbankanfrage hatte. Aber wenn ich jetzt mehrere Tabellen an unterschiedlichen Stellen im Skript abfrage, macht das ja auch mehr sinn.

2. du hast ja auch die datenbank-abfrage ja auch mit den typischen mysql_xxx-funktionen gemacht. Irgendwo (leider weiß ich nicht mehr wo) hab ich mal gesehen, dass man das auch mit SQL::Insert oder so machen kann. was ist das nun wieder?

Gruß
0 Punkte
Beantwortet von son_quatsch Experte (5.3k Punkte)
1.) Die Doku sagt es überdeutlich:
Nur bei SELECT, EXPLAIN, SHOW oder DESCRIBE Anweisungen liefert mysql_query() eine neue Ergebnis-Kennung, die Sie an die Funktion mysql_fetch_array() und andere Funktionen, die mit Ergebnistabellen umgehen können, übergeben können. Sind sie mit der Bearbeitung Ihrer Ergebnisse fertig, können Sie die belegten Resourcen durch den Aufruf von mysql_free_result() freigeben. Ist die Ausführung des Skripts abgeschlossen, wird der belegte Speicher automatisch freigegeben.
Auf deutsch: rufst du es nie auf, kannst du mit einem PHP-Skript auch mal den Speicher sprengen. Korrekt ist der Aufruf wiederum aber nur, wenn auch tatsächlich Rückgaben erzeugt wurden.

2.) Das war der Aufruf einer Klassenfunktion. Jene Klasse war aber von jemand anderem programmiert. Macht erst dann Sinn, wenn du etwas entwickelst, was auf mehreren DBMSe laufen soll (z.B. auch Oracle, MsSql oder PostgreSQL).
0 Punkte
Beantwortet von supermax Experte (4.8k Punkte)
Bei meinen Projekten, sowohl kleinere als auch größere, mache ich es im allgemeinen so:

Ich hab eine eigene include-Datei mit allen Datenbankfunktionen, die ich nur in jenen Scripts mittlels require_once() einbinde, die auch Datenbankzugriff benötigen. Diese Datei enhält Funktionen für Standard-Datenbankoperationen wie select, insert/replace, update usw., die auch bereits das korrekte escapen von feldnamen und Werten übernehmen.

Die Datenbankverbindung wird am Anfang der Datei geöffnet und die Datenbank ausgewählt, schlägt das fehl wird entweder auf eine Fehlerseite umgeleitet (falls das Script übers web aufgerufen wurde), ansonsten wird eine Fehlermeldung ausgegeben.

Der "Handle" der mySQL-Verbindung steht dann in einer globalen Variable, ich nenne sie meistens $DB, auf die in den Funktionen zugegriffen wird.

z.B. habe ich eine funktion db_select($sql), die das übergebene SQL-Statement ausführt (wenn es sich um SELECT, SHOW, DESCRIBE etc.) handelt, ansonsten wird false zurückgegeben, ansonsten werden die Ergebniszeilen eingelesen und in einem Array abgelegt, welches dann zurückgegeben wird.
0 Punkte
Beantwortet von
Ich danke euch für eure Antworten. hat mich echt ein stück weitergebracht. danke :-)
0 Punkte
Beantwortet von
Hallo,

ich nochmal...hab grad nochmal ne weitere Frage.
Und zwar hab ich ein kleines System, wo aber später mal jeder Benutzer unterschiedliche Rechte haben soll, bzw ich bestimmte Bereiche des SYstems modular jedem Benutzer hinzuschalten möchte oder eben auch nicht. WIe kann ich das am klügsten anstellen? Zuerst hatte ich mir gedacht, dass ich einfache eine Tabelle anlege und pro Modul eine Spalte mit 1 oder 0 setze, je nachdem ob der Benutzer darauf zugreifen darf oder nicht. Dann muss ich aber einerseits schon beim Menü prüfen was ich anzeigen darf und andererseits innerhalb des bereichs nochmal prüfen. Gibts bessere Konzepte?

habe bei Google unter anderem das hier gefunden, kann aber nicht wirklcih was damit anfangen (obwohl es interessant klingt):
http://www.goldmann.de/php-modular-programmieren_tipp_207.html

vielleicht könnt ihr mir hierzu ja noch ein zwei tipps geben.

Vielen dank schon mal im voraus
0 Punkte
Beantwortet von son_quatsch Experte (5.3k Punkte)
Und wo genau ist das Problem? Du brauchst doch die Datenbank nur einmal insgesamt abfragen nach dem Datensatz für den entsprechenden Nutzer. Und dieses Feld kannst du beliebig oft auswerten.

Oben merken wir uns doch auch alles im Feld $a1. Ob du dann die Elemente des Feldes einmal oder hundertmal auswertest ist doch Jacke wie Hose.

Dein Google-Fund gibt übrigens keine Tipps, sondern philosophiert nur etwas herum. Templates kommen für dich außerdem erst in Frage, wenn du deinen PHP-Code spielend im Griff hast und ...na sagen wir... mehr als 10 "Module" haben wirst.
0 Punkte
Beantwortet von
ok danke. dann werd ich das auch so machen. aber hätt ja sein können, dass es da noch ne sinnvollere methode gibt, man muss ja in die zukunft denken ;-)
...