0

In old mysql code, I had a query below which worked perfectly which is below:

$questioncontent = (isset($_GET['questioncontent'])) ? $_GET['questioncontent'] : '';

$searchquestion = $questioncontent;
$terms = explode(" ", $searchquestion);

$questionquery = "
SELECT q.QuestionId, q.QuestionContent, o.OptionType, an.Answer, r.ReplyType, 
  FROM Answer an 
  INNER JOIN Question q ON q.AnswerId = an.AnswerId
  JOIN Reply r ON q.ReplyId = r.ReplyId 
  JOIN Option_Table o ON q.OptionId = o.OptionId 

                 WHERE ";

    foreach ($terms as $each) {     
        $i++;         

        if ($i == 1){         
            $questionquery .= "q.QuestionContent LIKE `%$each%` ";     
            } else {         
                $questionquery .= "OR q.QuestionContent LIKE `%$each%` ";    
                 } 
                 }  

                 $questionquery .= "GROUP BY q.QuestionId, q.SessionId ORDER BY "; $i = 0; foreach ($terms as $each) {     
                     $i++;      

        if ($i != 1)         
        $questionquery .= "+";     
        $questionquery .= "IF(q.QuestionContent LIKE `%$each%` ,1,0)"; 
        } 

        $questionquery .= " DESC ";

But since that old mysql is fading away that people are saying to use PDO or mysqli (Can't use PDO because of version of php I have currently got), I tried changing my code to mysqli, but this is giving me problems. In the code below I have left out the bind_params command, my question is that how do I bind the parameters in the query below? It needs to be able to bind multiple $each because the user is able to type in multiple terms, and each $each is classed as a term.

Below is current mysqli code on the same query:

     $questioncontent = (isset($_GET['questioncontent'])) ? $_GET['questioncontent'] : '';

        $searchquestion = $questioncontent;
        $terms = explode(" ", $searchquestion);

        $questionquery = "
        SELECT q.QuestionId, q.QuestionContent, o.OptionType, an.Answer, r.ReplyType, 
          FROM Answer an 
          INNER JOIN Question q ON q.AnswerId = an.AnswerId
          JOIN Reply r ON q.ReplyId = r.ReplyId 
          JOIN Option_Table o ON q.OptionId = o.OptionId 

                         WHERE ";

    foreach ($terms as $each) {     
                $i++;         

                if ($i == 1){         
  $questionquery .= "q.QuestionContent LIKE ? ";     
                    } else {         
  $questionquery .= "OR q.QuestionContent LIKE ? ";    
                         } 
                         }  

 $questionquery .= "GROUP BY q.QuestionId, q.SessionId ORDER BY "; $i = 0; foreach ($terms as $each) {     
                             $i++;      

                if ($i != 1)         
                $questionquery .= "+";     
                $questionquery .= "IF(q.QuestionContent LIKE ? ,1,0)"; 
                } 

                $questionquery .= " DESC ";



            $stmt=$mysqli->prepare($questionquery);      
            $stmt->execute();
            $stmt->bind_result($dbQuestionId,$dbQuestionContent,$dbOptionType,$dbAnswer,$dbReplyType); 
            $questionnum = $stmt->num_rows();

1 Answer 1

4

Take a look at this SO Post that talks about the use of call_user_func_array with bind_param().

From the PHP Docs on mysqli_stmt_bind_param it says the following...

Note:

Care must be taken when using mysqli_stmt_bind_param() in conjunction with call_user_func_array(). Note that mysqli_stmt_bind_param() requires parameters to be passed by reference, whereas call_user_func_array() can accept as a parameter a list of variables that can represent references or values.

You'll want to use something like this

call_user_func_array(array($stmt, 'bind_param'), $terms);

and it's up to you to ensure that the correct number of ? characters appear in your SQL string $stmt.

[EDIT]

Here's a working example

// user entered search strings
$user_terms = array("a", "b", "c");

// append your wildcard "%" to all elements. you must use "&" reference on &$value
foreach ($user_terms as &$value) {
    $value = '%'.$value.'%';
}

$types = "";
for($i = 0; $i<sizeof($user_terms); $i++) {
    $types .= "s";
}

$terms = array_merge( array($types), $user_terms);

// the array $terms now contains: { "sss", "%a%", "%b%", "%c%" }

$sql = "SELECT ... ?,?,?"    // edit your sql here

$stmt = $mysqli->prepare($sql)

call_user_func_array(array($stmt, 'bind_param'), $terms);
Sign up to request clarification or add additional context in comments.

3 Comments

I will give it a go but I am guessing the line of code will be something like this:call_user_func_array( array ($stmt, 'bind_param'), $each); ? Also do I need to concatenate % with the $each as it is a LIKE statement? Could it be like this instead call_user_func_array( array ($stmt, 'bind_param'), $each = '%' . $each . '%'); ?
Ok, I tried this: call_user_func_array( array ($stmt, 'bind_param'), $each = '%' . $each . '%'); but if I enter in a correct term such as 'AAA', it cannot find the result as in the old mysql code, it did find the result
Updated answer with working code. The trick is to make sure the $types variable has the same number of s chars as your search $user_terms which must also match the number of ? chars in the $sql

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.