Archiv verlassen und diese Seite im Standarddesign anzeigen : Prepared Statements und bind_result mit wechselnder Anzahl von Parametern
Ich möchte mir ein Modul schreiben, dass ich in bei allen meinen Seiten verwenden kann. Dieses Modul soll alle Datenbankzugriffe organisieren (PHP/MySQL).
So weit, so einfach. Leider spricht der Vorteil von Prepared Statements, dass sie nicht manipulierbar sein sollen, gegen dieses Vorhaben.
Bisher binde ich die results so:
$GLOBALS['db_obj']->bind_result($GLOBALS['foo'], $GLOBALS['bar'], $GLOBALS['baz']);
Aber da natürlich die Anzahl meiner Parameter variiert, muss ich das jetzt irgendwie umgehen. Also hab ich Google bemüht und dabei call_user_func_array gefunden.
Zu meiner Schande muss ich gestehen, dass ich überhaupt nicht verstehe, was da genau passiert. Das geht so weit, dass ich nicht mal weiß, wo ich anfangen soll.
Ich hab ja schon mit function() gearbeitet. Aber mir ist überhaupt nicht klar, was ich mit einer Funktion machen soll, was nicht auch mit einer While-Schleife funktionieren müsste. Was es aber natürlich nicht tut.
So wie ich das sehe ist der Hauptunterschied zwischen function() und call_user_func_array() der, dass das eine mehrere Variablen und das andere ein Array mit den zu verarbeitenden Daten erhält. Aber wieso kann das jetzt mein Problem lösen?
Danke für jede Art Verständnishilfe.
mermshaus 21-06-2011, 18:14 So ungefähr ab hier ist der Post für mich nicht mehr nachvollziehbar:
Bisher binde ich die results so:
$GLOBALS['db_obj']->bind_result($GLOBALS['foo'], $GLOBALS['bar'], $GLOBALS['baz']);
Aber da natürlich die Anzahl meiner Parameter variiert, muss ich das jetzt irgendwie umgehen.
Dein $GLOBALS['db_obj'] ist ein MySQLi_STMT, nehme ich an?
Wie sollen da denn die Parameter variieren? Und wenn sie variieren, wieso übergibst du dann nicht einfach mehr Argumente an die Methode?
AmicaNoctis 21-06-2011, 18:16 Hallo und willkommen im Forum,
zunächst mal finde ich es bedenklich, mit $GLOBALS zu arbeiten. Damit schaffst du dir eine unübersichtliche Landschaft von wilden Variablen. Darin liegt z. B. schon einer der Vorteile von Funktionen, dass ihre Variablen nur dort gelten und Namenskollisionen ausgeschlossen sind.
Dein $db_obj ist eigentlich keins, sondern offensichtlich ein MySQLi_Stmt. Da ein solches nur eine ganz bestimmte Abfrage repräsentiert, kann es eigentlich gar nicht sein, dass du dort unterschiedliche Parameteranzahlen hast.
Wenn du allerdings meinst, dass du ein Codestück für völlig unterschiedliche Statements verwendest, dann verstehe ich es, aber mir leuchtet dabei nicht ein, wei du das ohne Funktionen bewerkstelligen willst (die ja jeweils einen eigenen Gültigkeitsbereich für jeden Aufruf haben).
Zum Thema call_user_func_array: Damit kann man Parameterlisten für Funktionen dynamisch zusammenbauen, statt die Parameter fest in den Aufruf einzubauen.
myFunc($a, $b, $c); // Es werden 3 Parameter übergeben
myFunc($d, $e); // Es werden 2 Parameter übergeben
$params = array(); // dynamische Parameter; können unterschiedlich viele sein
$params[] = 1;
$params[] = "Hallo Welt!";
$params[] = false;
myFunc($params); // FALSCH, denn jetzt wird nur ein Parameter (ein Array) übergeben
// Lösung:
call_user_func_array("myFunc", $params); // jedes Element wird sozusagen als einzelner Parameter übergeben
// Das kann man sich ungefähr so vorstellen:
switch (count($params)) {
case 0: myFunc(); break;
case 1: myFunc($params[0]); break;
case 2: myFunc($params[0], $params[1]); break;
case 3: myFunc($params[0], $params[1], $params[2]); break;
case 4: myFunc($params[0], $params[1], $params[2], $params[3]); break;
// u. s. w.
}
Gruß,
Amica
So hab ich das bisher gemacht:
if ($GLOBALS['db_obj']=$GLOBALS['db']->prepare($GLOBALS['db_sql_stm'])) {
$GLOBALS['db_obj']->execute();
$GLOBALS['db_obj']->bind_result($GLOBALS['foo'], $GLOBALS['bar'], $GLOBALS['baz']);
$GLOBALS['cou_ds']=0;
while ($GLOBALS['db_obj']->fetch()) {
$GLOBALS['pag'][$GLOBALS['cou_ds']]['pag_id']=$GLOBALS['pag_id'];
$GLOBALS['pag'][$GLOBALS['cou_ds']]['foo']=$GLOBALS['foo'];
$GLOBALS['pag'][$GLOBALS['cou_ds']]['bar']=$GLOBALS['bar'];
$GLOBALS['pag'][$GLOBALS['cou_ds']]['baz']=$GLOBALS['baz'];
$GLOBALS['cou_ds']++;
}
$GLOBALS['db_obj']->close();
} else {
$GLOBALS['err_db']='Error '.$GLOBALS['db']->errno.' - '.$GLOBALS['db']->error;
echo '<br>'.$GLOBALS['err_db'].'<br>';
}Okay, das mit der Gültigkeit der Variablen nur innerhalb der Funktion hatte ich schon wieder vergessen.
Genau, ich möchte ein Modul für alle Statements verwenden. Und ich will lieber eine Funktion verwenden als ein switch/case-Konstrukt.
Aber, ich will es halt verstehen. Leider verwirrt mich auch Dein Beispiel, Amica. Sorry, aber bei diesem call_user_func_array hab ich das Gefühl, als sehe ich den Wald vor lauter Bäumen nicht.
Wenn das Funktionen sein sollen, dann fehlt der Ausdruck "function", oder? Und auch irgendwas, was dem dem Objekt sagt, was damit geschehen zu hat. Oder liege ich völlig falsch?
myFunc($a, $b, $c); // Es werden 3 Parameter übergeben
myFunc($d, $e); // Es werden 2 Parameter übergebenDas is klar, hier setzt Du ein Array.
$params = array(); // dynamische Parameter; können unterschiedlich viele sein
$params[] = 1;
$params[] = "Hallo Welt!";
$params[] = false;Das sagt mir wieder nix:
myFunc($params); // FALSCH, denn jetzt wird nur ein Parameter (ein Array) übergebenOkay, damit könnte ich was anfangen, wenn ich nicht 2 unterschiedliche myFunc hätte und darin etwas mehr stünde.
// Lösung:
call_user_func_array("myFunc", $params); // jedes Element wird sozusagen als einzelner Parameter übergebenDas will ich nicht: :)
// Das kann man sich ungefähr so vorstellen:
switch (count($params)) {
case 1: myFunc($params[0]); break;
case 2: myFunc($params[0], $params[1]); break;
case 3: myFunc($params[0], $params[1], $params[2]); break;
case 4: myFunc($params[0], $params[1], $params[2], $params[3]); break;
// u. s. w.
} Sorry, wenn ich Euch Eure Zeit stehle, mit meinem Unverständnis.
AmicaNoctis 21-06-2011, 19:20 Also ich sehe bei deinen $GLOBALS den Wald vor lauter Bäumen nicht, was aber z. T. daran liegt, dass ich mir die Augen zuhalten muss. ;)
Das function-Schlüsselwort wird bei der Definition einer Funktion benötigt, aber nicht bei ihrem Aufruf.
// Definition
function multiply ($x, $y) {
return $x * $y;
}
// Aufrufe
$prod = multiply(3, 4); // prod ist jetzt 12
echo multiply($prod, 13); // 156 wird ausgegeben
Hab mir das nochmal mit dem Register Golbals angesehen. Jetzt weiß ich auch nicht mehr, warum ich mir damals angewöhnt hab, die globalen Variablen als $GLOBALS auszuzeichnen. :rolleyes:
Nun gut, so sieht der Code jetzt aus:
if ($db_obj=$db->prepare($db_sql_stm)) {
$db_obj->execute();
$db_obj->bind_result($foo, $bar, $baz);
$cou_ds=0;
while ($db_obj->fetch()) {
$pag[$cou_ds]['foo']=$foo;
$pag[$cou_ds]['bar']=$bar;
$pag[$cou_ds]['baz']=$baz;
$cou_ds++;
}
$db_obj->close();
} else {
$err_db='Error '.$db->errno.' - '.$db->error;
echo '<br>'.$err_db.'<br>';
}So sieht übrigens $db_sql_stm beispielsweise aus.
SELECT foo, bar, baz FROM pag;Jetzt hab ich das mal verbaut:
function bnd_res ($db_obj, $db_cm) // Das natürlich vor dem Aufruf
{
$db_obj->bind_result($db_cm);
}
call_user_func_array('bnd_res', $db_cm); // Das anstatt $db_obj->bind_result($foo, $bar, $baz);Dann bekomme ich das:
Fatal error: Call to a member function bind_result() on a non-object in x.inc on line x
Aber das war natürlich klar. Ist es nicht so, dass wenn das funktioniert hätte, ich gar keine Funktion brauchen würde, sondern einfach das $db_obj->bind_result($db_cm); anstatt $db_obj->bind_result($foo, $bar, $baz); schreiben müsste?
Ist natürlich ne rhetorische Frage. Habs ja ausprobiert. :)
Was muss ich ändern, damit ich mit variabler Anzahl an Parametern arbeiten kann?
AmicaNoctis 22-06-2011, 11:18 Warum nimmst du nicht PDO (http://de3.php.net/manual/de/class.pdo.php)? Da kannst du mit Prepared Statements arbeiten, ohne gleichzeitig das Ergebnis zeilenweise binden zu müssen.
Hab mir das nochmal mit dem Register Golbals angesehen. Jetzt weiß ich auch nicht mehr, warum ich mir damals angewöhnt hab, die globalen Variablen als $GLOBALS auszuzeichnen. :rolleyes:
Du sollst gar keine globalen Variablen verwenden! Global ist böse! Kein Mensch braucht global.
|
-
- |