Maison  >  Questions et réponses  >  le corps du texte

Construire une requête SELECT en tant qu'instruction préparée par MySQLi en utilisant un nombre dynamique de conditions LIKE

J'essaie d'écrire des instructions préparées pour la saisie de l'utilisateur. Le nombre de paramètres change en fonction de la saisie de l'utilisateur. Oam essaie ce code

Code PHP :

$string          = "my name";
$search_exploded = explode( " ", $string );
$num             = count( $search_exploded );
$cart            = array();
for ( $i = 1; $i <= $num; $i ++ ) {
    $cart[] = 's';
}
$str          = implode( '', $cart );
$inputArray[] = &$str;
$j            = count( $search_exploded );
for ( $i = 0; $i < $j; $i ++ ) {
    $inputArray[] = &$search_exploded[ $i ];
}
print_r( $inputArray );
foreach ( $search_exploded as $search_each ) {
    $x ++;
    if ( $x == 1 ) {
        $construct .= "name LIKE %?%";
    } else {
        $construct .= " or name LIKE %?%";
    }
}
$query = "SELECT * FROM info WHERE $construct";
$stmt  = mysqli_prepare( $conn, $query );
call_user_func_array( array( $stmt, 'bind_param' ), $inputArray );
if ( mysqli_stmt_execute( $stmt ) ) {

    $result = mysqli_stmt_get_result( $stmt );
    if ( mysqli_num_rows( $result ) > 0 ) {
        echo $foundnum = mysqli_num_rows( $result );
        while( $row = mysqli_fetch_array( $result, MYSQLI_ASSOC ) ) {

            echo $id = $row['id'];
            echo $name = $row['name'];
        }
    }
}

Quand je print_r($inputArray) le résultat est :

Array ( [0] => ss [1] => my [2] => name )

Aucune erreur n'est affichée dans le journal des erreurs.

Qu'est-ce qui n'a pas fonctionné ?

P粉269847997P粉269847997181 Il y a quelques jours316

répondre à tous(2)je répondrai

  • P粉826429907

    P粉8264299072024-03-26 14:50:12

    Écrivez un gestionnaire de requêtes générique et transmettez-lui votre requête, votre tableau de paramètres et votre liste de types de paramètres. Renvoie un ensemble de résultats ou de messages. Il s'agit de ma version personnelle de mysqli (j'utilise principalement PDO, mais j'ai configuré des fonctionnalités similaires pour cela). Faites de même pour les insertions, les mises à jour et les suppressions. Ensuite, conservez simplement votre bibliothèque et utilisez-la pour tout ce que vous faites :) Notez que si vous commencez par cela, vous souhaiterez peut-être mieux gérer les erreurs de connexion, etc.

    connect_error) {
          return false;
        }
        return $con;
    }
    
    // generic select function.
    // takes a query string, an array of parameters, and a string of
    // parameter types
    // returns an array - 
    //   if $retVal[0] is true, query was successful and returned data
    //   and $revVal[1...N] contain the results as an associative array
    //   if $retVal[0] is false, then $retVal[1] either contains the 
    //   message "no records returned" OR it contains a mysql error message
    
    function selectFromDB($query,$params,$paramtypes){
    
        // intitial return;
        $retVal[0]=false;
    
        // establish connection
        $con = getDBConnection();
        if(!$con){
            die("db connection error");
            exit;
        }
    
        // sets up a prepared statement
        $stmnt=$con->prepare($query);
        $stmnt->bind_param($paramtypes, ...$params);
        $stmnt->execute();
    
        // get our results
        $result=$stmnt->get_result()->fetch_all(MYSQLI_ASSOC);
        if(!$result){
        $retVal[1]="No records returned";
        }else{
            $retVal[0]=true;
            for($i=0;$iclose();
    
        return $retVal;
    
    }
    
    $myusername=$_POST['username'];
    $mypassword=$_POST['password'];
    
    // our query, using ? as positional placeholders for our parameters
    $q="SELECT useridnum,username FROM users WHERE username=? and password=?";
    
    // our parameters as an array - 
    $p=array($myusername,$mypassword);
    
    // what data types are our params? both strings in this case
    $ps="ss";
    
    // run query and get results
    $result=selectFromDB($q,$p,$ps);
    
    // no matching record OR a query error
    if(!$result[0]){
        if($result[1]=="no records returned"){
            // no records
            // do stuff
        }else{
            // query error
            die($result[1]);
            exit;
        }   
    }else{  // we  have matches!
        for($i=1;$i$val){
                print("key:".$key." -> value:".$val);
            }
        }
    }
    
    ?>

    répondre
    0
  • P粉787806024

    P粉7878060242024-03-26 12:36:45

    % Paramètres surround, pas d'espaces réservés.

    Mon extrait de code utilisera la syntaxe mysqli orientée objet, plutôt que la syntaxe procédurale démontrée par votre code.

    Vous devez d'abord préparer les ingrédients nécessaires :

    1. Expression de clause WHERE -- séparée par OR
    2. Type de données de valeur - votre valeur est une chaîne, utilisez donc "s"
    3. Paramètres à lier aux déclarations préparées

    Je vais combiner #2 et #3 dans une variable pour un "déballage" plus facile à l'aide de l'opérateur splat (...). La chaîne de type de données doit être le premier élément, puis un ou plusieurs éléments représenteront la valeur liée.

    En tant qu'inclusion logique, s'il n'y a pas de condition dans la clause WHERE, il n'y a aucun avantage à utiliser une instruction préparée ; il suffit d'interroger directement la table.

    Code : (Démo PHPize.online)

    $string = "Bill N_d Dave";
    
    $conditions = [];
    $parameters = [''];
    foreach (array_unique(explode(' ', $string)) as $value) {
        $conditions[] = "name LIKE ?";
        $parameters[0] .= 's';
        // $value = addcslashes($value, '%_'); // if you want to make wildcards from input string literal. https://stackoverflow.com/questions/18527659/how-can-i-with-mysqli-make-a-query-with-like-and-get-all-results#comment132930420_36593020
        $parameters[] = "%{$value}%";
    }
    // $parameters now holds ['sss', '%Bill%', '%N_d%', '%Dave%']
    
    $query = "SELECT * FROM info";
    if ($conditions) {
        $stmt = $mysqli->prepare($query . ' WHERE ' . implode(' OR ', $conditions));
        $stmt->bind_param(...$parameters);
        $stmt->execute();
        $result = $stmt->get_result();
    } else {
        $result = $conn->query($query);
    }
    foreach ($result as $row) {
        echo "
    {$row['name']}
    \n"; }

    Pour tous ceux qui recherchent des techniques de requêtes dynamiques similaires :

    répondre
    0
  • Annulerrépondre