2013-02-20 2 views
1

Je fais ma première classe de base de données pour le moment et actuellement je fais la fonction de préparation.Personnaliser mysqli préparer fonction

Cette fonction permet de saisir une requête SQL, puis un tableau contenant les variables de l'instruction. J'ai des problèmes avec la liaison des paramètres à l'instruction.

Voici comment la fonction ressemble maintenant

public function prepare($query, $var) { 
    $types = ''; 
    foreach($var as $a) { 
     $type = gettype($a); 
     switch($type) { 
      case 'integer': 
       $types .= 'i'; 
       break; 

      case 'string': 
       $types .= 's'; 
       break; 

      default: 
       exit('Invalid type: ' . $a .' ' . $type . '(' . count($a) . ')'); 
       break; 
     } 
    } 

    $stmt = self::$connection->prepare($query); 
    $stmt->bind_param($types, $var); // How do I do here?? 
    $stmt->execute(); 
    $result = $stmt->get_result(); 
    while($row = $result->fetch_assoc()) { 
     print_r($row); 
    } 
} 

Tout fonctionne comme je le veux (je sais que cette fonction pourrait faire un peu de polissage, mais il fait ce qu'il doit faire). J'ai commenté la ligne où j'ai de la difficulté à trouver quoi faire. $ var est un tableau et si je me souviens correctement, les variables doivent être passées séparément avec une virgule. C'est là que je suis désemparé.

+0

Un conseil: plus les mots génériques sont définis, plus votre question attire l'attention. Il n'a que * sept * vues à la fois, tout cela grâce à l'étiquetage sophistiqué que vous choisissez. 'php' est toujours un bon choix. –

Répondre

1

L'idée même de votre propre classe de base de données est géniale.
Très peu de gens ici le partagent, pour une raison quelconque, préfère les appels API api partout dans leur code.
Alors, vous allez encore plus loin.
Cependant, voici quelques objections:

  1. Ne pas utiliser la mysqli pour votre première propre classe de base de données si vous allez utiliser des instructions natives préparées.
    Utilisez plutôt PDO. Cela vous épargnera une tonne de maux de tête.
  2. En dépit du fait cette fonction fonctionne bien pour vous, cela n'a pas beaucoup de sens:
    • switch($type) bloc de code est inutile. Mysql peut comprendre chaque valeur scalaire comme une chaîne - de sorte que vous pouvez lier chaque valeur comme s sans problème.
    • la plupart des entiers provenant du côté client ont quand même un type de chaîne.
    • il existe certains types légitimes comme float ou NULL ou un objet qui peut renvoyer une chaîne. Donc, l'automatisation ne fonctionnera pas ici. Si vous voulez distinguer les différents types, vous devez implémenter des espaces réservés avec caractères de type à la place.
    • Jamais utilisez exit dans vos scripts. throw new Exception('put here your error message') à la place.
  3. Il ne s'agit pas réellement d'une fonction de préparation car elle s'exécute également. Alors, donnez-lui le nom plus générique

Mais maintenant à votre problème
Il est la conséquence directe de l'utilisation mysqli. C'est un cauchemar lorsqu'il s'agit de déclarations préparées. Pas même avec la liaison mais avec la récupération de vos données (parce que get_result() ne fonctionne pas partout, et après avoir créé votre application localement, vous verrez que cela ne fonctionne pas sur l'hébergement partagé). Vous pouvez vous faire une idée en regardant this bunch of code servi à cette fin - pour lier le nombre dynamique de variables. Alors, éloignez-vous de mysqli autant que vous le pouvez.
Avec PDO votre fonction sera aussi simple que cela

public function query($query, $var=array()) 
{ 
    $stmt = self::$connection->prepare($query); 
    $stmt->execute($var); 
    return $stmt->fetchAll(PDO::FETCH_ASSOC); 
} 
// and then used 
$data = $db->("SELECT 1"); 
print_r($data); 

Vous pouvez take a look at my class pour obtenir quelques idées.
N'hésitez pas à poser des questions concernant les classes de base de données - c'est une bonne chose, et je suis heureux que vous alliez de cette façon.

Pour répondre aux questions des commentaires.

Pour vous aider, vous n'êtes pas le seul utilisateur du site. Il y a aussi des visiteurs innocents. Contrairement à vous, ils n'ont pas besoin de messages d'erreur, et ils ont peur avec un comportement étrange et un manque de contrôles familiers.

exit() avec le message d'erreur fait beaucoup de choses mauvaises

  • renvoyait un message d'erreur sur, révélant un système à un attaquant internals potentiel
  • faire peur utilisateur innocent avec un message étrange. "Qu'est-ce que c'est? Qui est invalide? Est-ce ma faute ou quoi? Ou peut-être que c'est un virus? Mieux vaut quitter le site du tout" - les pense.
  • en supprimant le script au milieu, ce qui peut provoquer une déchirure du dessin (ou aucun dessin)
  • en lisant irrémédiablement le script. alors exception levée peut être pris et gracieusement traité

Lors de la connexion à PDO, pas besoin de jeter quoi que ce soit ici que l'exception déjà jeté par AOP. Alors, se débarrasser de try ... catch et juste laisser une ligne:

self::$connection = new PDO($dsn, $user, $pass); 

puis créez une coutume exception handler de travailler en 2 modes:

  • sur un serveur de développement laisser jeter le message sur l'écran.
  • sur un serveur en laissez-le journal l'erreur tout en montrant la page d'erreur générique à l'utilisateur

Utilisez try ... catch que si vous ne voulez pas mourir tout script - par exemple pour gérer récupérable seulement. Par ailleurs, PDO ne lance pas d'exception sur connexion par défaut. Vous devez le configurer manuellement:

$opt = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); 
self::$connection = new PDO($dsn, $user, $pass, $opt); 
+0

Je sais que PDO est bien meilleur que Mysqli mais j'ai toujours été trop paresseux pour passer à PDO, je suppose que je vais commencer maintenant! Pourquoi ne devrais-je pas utiliser exit()? Quelle est la différence entre lancer une exception et utiliser exit()? Comment est-ce? Dois-je jeter l'exception ici aussi? try { self :: $ connexion = nouveau PDO ($ dsn, $ utilisateur, $ pass); } catch (PDOException $ e) { exit ('Échec de la connexion:'. $ E-> getMessage(); } – Unidan

Questions connexes