Jump to content

Problem with mysqli and bind variables in php 5.3


darwin_tech

Recommended Posts

Hi I have an infuriating problem which is stalling me with two large projects for a well known NGO right now.

 

I am using mysqli and bound variables where the number of variables to bind is dependent on user input. I have a version of the code below working in php 5.2 but as of php 5.3 this method is no longer valid, specifically due to a change in the behavior of call_user_func_array with bound variables as arrays. I have read about this problem eslewhere but cannot get any of the workarounds to work with my example. Any help would be greatly appreciated.

 

# $parts    is an array with variable number of values
# $type     is an array with variable number of values
# $params   is an array with variable number of values



$query = 'SELECT SQL_CALC_FOUND_ROWS DISTINCT 
taxon.TaxonID,
FROM taxon
WHERE
. join('', $parts) . 
" ORDER BY taxon.TaxonID";



# Prepare stmt
if ($stmt = $mysqli->prepare($query)) {


   call_user_func_array (array($stmt, 'bind_param'),array_merge(array(join('', $type)), $params)); 


# execute
$stmt->execute();


# bug info
echo $stmt->errno, ':', $stmt->error;

        #store result
$stmt->store_result();

# bind results
$stmt->bind_result($ID);

        # fetch values 
        while ($stmt->fetch()) {

    	  # results code goes here!
    		
        }

       # free memory
       $stmt->free_result();

       # close statement 
       $stmt->close();
}

Link to comment
Share on other sites

@PFMaBiSmAd

 

Yes, I had come across this solution but for some reason I cannot get it to work with my code. I still return the error

 

2031:No data supplied for parameters in prepared statement

 

 

is there perhaps some small detail I'm missing? I include my modified code below just in case ->

 

 


# Prepare stmt
if ($stmt = $mysqli->prepare($query)) {

   # merge the type array with the parameters array
   $params = array_merge($type, $params);
   
   # modified bind 
   call_user_func_array(array($stmt, 'bind_param'), refValues($params));

   # execute
   $stmt->execute();

       # results and clean up!
}

function refValues($arr){
        if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+
        {
            $refs = array();
            foreach($arr as $key => $value)
                $refs[$key] = &$arr[$key];
            return $refs;
        }
        return $arr;
    }

 

 

Regards,

 

Sam

Link to comment
Share on other sites

OK, for anyone who might have stumbled across the same problem, I have a found a solution!

 

mostly it is detailed at http://php.net/manual/en/mysqli-stmt.bind-param.php

 

One key factor was that $type cannot be passed as an array. Here I use the join function to pass $type as a string.

 

Hope this may be useful...

 

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

$type = join('', $type);

call_user_func_array('mysqli_stmt_bind_param', array_merge (array($stmt, $type), refValues($params)));

$stmt->execute();
}

function refValues($arr)
{ 
    if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+ 
    { 
        $refs = array(); 
        foreach($arr as $key => $value) 
            $refs[$key] = &$arr[$key]; 
         return $refs; 
     } 
     return $arr; 
}

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.