3 votes

MySQLi Prepared statements - Fonction d'encapsulation pour SELECT

J'ai récemment commencé à utiliser les instructions préparées de MySQLi. Je n'ai pas aimé le nombre de lignes de code qui étaient nécessaires pour une simple instruction select. J'ai donc créé une fonction wrapper, voir le code ci-dessous les questions ci-dessous. Note : get_results() ou PDO n'est pas une option pour moi.

Mes questions sont les suivantes :

  1. Cela ralentira-t-il sensiblement les performances ?

  2. L'utilisation d'un tableau de résultats nécessitera-t-elle plus de mémoire ?

  3. Le fait que $stmt->close() précède le retour va-t-il causer des problèmes ? Par exemple, peut-être que les données du tableau de résultats sont également libérées de la mémoire ?

  4. Dois-je fermer ou libérer quoi que ce soit d'autre (à part la fermeture de la connexion à la base de données) ?

  5. Voyez-vous d'autres problèmes avec la fonction ou pourrait-elle être améliorée ?

Code :

class DatabaseHelper{

static function select($con, $query, $formats, $params){
    $a_params = array();

    $param_type = '';
    $n = count($formats);
    for($i = 0; $i < $n; $i++) {
        $param_type .= $formats[$i];
    }

    $a_params[] = & $param_type;

    for($i = 0; $i < $n; $i++) {
        $a_params[] = & $params[$i];
    }

    $stmt = $con->prepare($query);
    call_user_func_array(array($stmt, 'bind_param'), $a_params);
    $stmt->execute();

    $meta = $stmt->result_metadata();
    while ($field = $meta->fetch_field()) {
        $columns[] = &$row[$field->name];
    }

    call_user_func_array(array($stmt, 'bind_result'), $columns);

    while ($stmt->fetch()) {
        foreach($row as $key => $val) {
            $x[$key] = $val;
        }
        $results[] = $x;
    }
    $stmt->close();
    return $results;
}

}

Utilisé comme ceci par exemple :

$users = DatabaseHelper::select($conn, "SELECT name,username FROM users WHERE id > ?", "i", array(30));
foreach ($users as $row){
    echo $row['username'] . " ". $row['name'] . "<br />";
}

0voto

Cela ralentira-t-il sensiblement les performances ?

Non.

L'utilisation d'un tableau de résultats nécessitera-t-elle plus de mémoire ?

Non, tant que vous sélectionnez des quantités raisonnables de données. Dans une application moderne, vous devez de toute façon sélectionner d'abord toutes les données, car la logique commerciale doit être séparée de la logique d'affichage.

Est-ce que le $stmt->close() avant le retour va poser des problèmes ? Par exemple, peut-être que les données du tableau de résultats sont également libérées de la mémoire ?

Pourquoi ne pas essayer et voir ?

Dois-je fermer ou libérer quelque chose d'autre (à part la fermeture de la connexion à la base de données) ?

Il n'est pas non plus nécessaire de fermer une déclaration.

Voyez-vous d'autres problèmes avec la fonction ou pourrait-elle être améliorée ?

  • Tout d'abord et avant tout. Comme c'est une classe que vous écrivez, et non une fonction, il est absolument inutile de passer la connexion en paramètre. Faites-en une propriété statique.
  • Je suggère également de faire des types le dernier paramètre avec une valeur par défaut. Dans la plupart des cas, il n'est pas nécessaire de se préoccuper des types - une chaîne par défaut suffit.
  • De plus, comme votre version de PHP est 5.6, vous pouvez utiliser l'opérateur splat juste pour réduire la quantité de code. Vous pouvez vérifier cette réponse de ma part pour les détails
  • Je vous suggère également de diviser votre fonction en plusieurs méthodes - une pour exécuter la requête et d'autres pour obtenir les résultats. Cela vous permettra de réutiliser le même code pour toutes sortes de requêtes.
  • assurez-vous que vous êtes en surveillant les erreurs mysqli comme expliqué ici

Donc, idéalement, vous devriez appeler votre requête de cette façon

$users = DatabaseHelper::getAll("SELECT name,username FROM users WHERE id > ?", [30]);
foreach ($users as $row){
    echo $row['username'] . " ". $row['name'] . "<br />";
}

où la méthode getAll() utilise la méthode query() en interne pour effectuer une requête et ensuite récupérer tous les résultats. De même, vous pouvez écrire les méthodes getRow() et getOne().

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X