Bonjour a tous,

je suis forcer d'adapter un site sur un serveur php 5.0.4 et la classe PDO ne fonctionne qu'a partir de la version 5.1 de PHP.

Je dois donc soit refaire toutes mes requêtes sql...c'est long...
Ou sinon refaire le script de connexion a la BDD...c'est mieux déjà :-)

J'utilise le script de Grafikart à savoir celui là :

<?php
class DB{

    private $host = '';
    private $username = '';
    private $password = '';
    private $database = '';
    private $db;

    public function __construct($host = null, $username = null, $password = null, $database = null){
        if($host != null){
            $this->host = $host;
            $this->username = $username;
            $this->password = $password;
            $this->database = $database;
        }

        try{
            $this->db = new PDO('mysql:host='.$this->host.';dbname='.$this->database, $this->username, $this->password, array(
                    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8',
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING
                ));
        }catch(PDOException $e){
            die('<h1>Impossible de se connecter a la base de donnée</h1>');
        }

    }

    public function query($sql, $data = array()){
        $req = $this->db->prepare($sql);
        $req->execute($data);
        return $req->fetchAll(PDO::FETCH_OBJ);
    }

}
?>

Quelqu'un vois comment l'adapter avec mysqli car depuis tout a l'heure je galère...
Sachant que mes requetes 'SELECT' ne sont pas préparées.

Merci d'avance

9 réponses


Tu ne fais qu'éviter ton problème sans réellement le résoudre.
Primo PDO est de loin supérieur à mysqli (PDO est du vrai orienté objet, il a en plus les paramètres nommés et les requêtes prépares que mysqli n'as pas donc je ne vois pas l’intérêt a utilisé une techno moins "efficace". Bref

Secundo dans ton choix tu ne fait que garder au chaud pour d'éventuels personnes malveillantes un tas de vulnérabilités PHP qui sont corrigés chez tout le monde sauf toi (php 5.0.4 doit daté de plus de 7 ans!!!!)
Je te conseil donc de prendre ton temps, de mettre à jour tes requêtes et surtout de mettre a jour ton serveur web, !
Et je pense que ca sera l'occasion pour apporter quelques mise à jour ou pour faire une petite refonte

Tout ceci bien sur au niveau de la production et non de l'exploitation. Fait tes mises à jour de requêtes, fait une recherches via notepad++ dans le répertoire contenant tes sources pour voir s'il n'existe pas une modification non faite dans un fichier caché quelques part puis après tes tests tu met le tout en exploitation (après bien sur l'opération de sauvegarde/backup de la version précédente)
Tu avertis tes utilisateurs qu'ils seront éventuellement des bétas testeurs d'une version améliorée de ton appli web et qu'ils peuvent et doivent te contacter en cas de soucis.

Axis
Auteur

Je travail dans un domaine bien particulier et je ne peux mettre a jour le serveur...d'où l'OBLIGATION d'utiliser mysqli...

Sinon crois mois j'aurais gardé ma structure qui fonctionne très bien sur PHP 5.4...

D'accord! .... :) je travail également dans un domaine particulier (la vente de poterie en ligne) et je trouve inconscient et fou le fait de ne pas prendre au sérieux les risques que peuvent causer l'oubli (volontaire) d'une faille de sécurité

Bref voici un petit lien j'espère qu'il répondra à tes questions, sinon ben je suis toujours la :)
pdo-vs-mysqli-which-should-you-use
Oubli dans ce lien le fait qu'il t'insite a rester en pdo et regarde les codes parallèles qu'il fait entre pdo et mysqli

Bonne continuation :)

Axis
Auteur

lol je parlais pas d'un domaine particulier comme celui ci ;-)

Enfin bref, je bloque ici :

$query->bind_param();

Moi je renvoi un tableau ici avec desfois 1 ou plusieurs variables...et apparement il n'est pas possible d'inserer un tableau dans bind_param() non ?

Non! :) bindparam c'est pour les variables (en référence) de tes requêtes préparées via mysqli_prepare()
tu as la fonction call_user_func_array() qui accepte comme paramètre un....... TADAAAAAAAA!!!!! tableau.

la un exemple (genre j'ai tout compris)

<?php
           $mysqli = new mysqli($this->host,$this->username,$this->password,$this->database);
           $parametre = array("18", "tuto php", "tarzan", date(),"pouet pouet");
           $requete = "INSERT INTO Post (id, title, auteur, date, blabla) VALUES (?, ?, ?, ?, ?)";  
           $stmt = $mysqli->prepare($requete) or die ("probleme!");
           call_user_func_array(array($stmt, 'bind_param'), $parametres);          
           $stmt->execute();

Quelques liens intéressants d’où je me suis inspiré (c'est notre façon a nous web-developper de dire piquer le code!)
http://php.net/manual/fr/mysqli-stmt.bind-param.php
http://forums.phpfreaks.com/topic/143044-solved-call-user-func-array-help-needed-for-very-long-mysqli-statement/
http://php.net/manual/fr/function.call-user-func-array.php

Axis
Auteur

J'etais plus parti sur un truc du genre :

public function query($sql,$data = array()){
        $stmt = $this->db->prepare($sql);
        $bind = '';
        $param = '';
        foreach ($data as $key => $value) {
            $bind .='s';
            $param .= '\''.$value.'\', ';

        }
        $param = substr($param, 0, strlen($param)-2);
        echo $param;
        $stmt->bind_param('$bind', $param);
        $stmt->execute();
        return $stmt;
    }

Mais ça marche pô !

Et pour call_user_func_array(), ça me met ça :

Warning: Wrong parameter count for mysqli_stmt::bind_param()

pardon pourrais je avoir le code que tu as mis avec call_user_func_array()
merchii :)

sinon pour le code que tu m'as mis pourquoi le simple quotte à la ligne 14 ??? :)
$stmt->bind_param( ' $bind ' , $param);

Axis
Auteur
public function query($sql, $data = array()){
        var_dump($data);

        $stmt = $this->db->prepare($sql);
         call_user_func_array(array($stmt, 'bind_param'), $data);
        $stmt->execute();
        return $stmt;
    }

$sql = "SELECT * FROM fc_users WHERE mdp=? AND login=? AND active=1";

et

$data = array($mdp, $login);

_____________

Pour le simple quote c'etait pouir debug car sans ça ne marche pas non plus :(

j'ai pas très bien compris ce que j'ai lu mais c'est du a des changements au niveau php? (ce qui est bizarre c'est que ton erreur est apparue pour ceux ayant une version supérieur à 5.3.. bref tu ne perd rien a essayé :)

private function refValues(&$arr) // <--- la c'est selon ton code, je vois pas le tout mais si tu n'est pas dans une classe enkeve ce private
// et l'accès en $this->refValues à la ligne 23
{
    //Reference is required for PHP 5.3+
    if (strnatcmp(phpversion(),'5.3') >= 0)
    {
        $refs = array();
        foreach(array_keys($arr) as $key)
        {
            $refs$key] = &$arr$key];
        }
        return $refs;
    }
    return $arr;
}

public function query($sql, $data = array()){
    // var_dump($data);
    $stmt = $this->db->prepare($sql);
    call_user_func_array(array($stmt, 'bind_param'), $this->refValues($data));
    $stmt->execute();
    return $stmt;
}
// il y a également cette variante (la moins utilisé et j'ai pas lu de commentaire encourageant
    private function refValues($arr){
        $refs = array();
        foreach($arr as $key => $value)
        $refs$key] = &$arr$key];
        return $refs;
    }

Accès directs aux sources sur la page de mysqli_stmt::bind_param (php.net)
source 1
en accord avec source 2
source 3
Bon... j'vais pas tous te les pondres :) mais d'après ce dernier commentaire c'est effectivement ce qu'il y a de plus proche avec ton problème

:) j'attend de savoir si ca t'a permis de surmonter le problème (Wrong parameter count for mysqli_stmt::bind_param())