PHP 8.5.0 Alpha 1 available for testing

Voting

: max(eight, two)?
(Example: nine)

The Note You're Voting On

laurence dot mackenzie at stream dot com
11 years ago
I just came across a very strange behaviour when using bind_param() with a reflection class. I figured I ought to post it here to save anyone else who comes across it from banging their head against their desk for an hour (as I just did).

First, some background: I have a set of classes, one per file format (i.e. CSV, HTML table, etc), which import data from flat files to a temporary table in my database. The class then transforms the data to 3NF.

I'm using a reflection class to pass an array to mysqli->bind_param() because the column counts and types are variable. The code (simplified) I am having issues with is:

<?php

/* Code that loops through the rows and columns in the
* flat file and appends the MySQLi 'type' letter to the
* $typeString variable and appends the actual value
* to the $data array. I left the code out because it's
* (probably) not relevant and would bloat the post.
*/
$stmtInsert = $db->prepare('INSERT.....');
$typeString = 'ississis';
$data = array(1, 'two', 'three', 4, 'five', 'six', 7, 'eight');

/* Here's where the actual strangeness starts happening
*/

// Merge the parameter types with the parameter values
$data = array_merge((array) $typeString, $data);

// Create the reflection class
$ref = new \ReflectionClass('mysqli_stmt');

// Get the bind_param method
$method = $ref->getMethod('bind_param');

// Invoke it with $data
$method->invokeArgs($stmtInsert, $data);

// Execute the statement
$stmtInsert->execute();

}
?>

Oddly, in one (and only one) case it started throwing "Warning: Parameter 41 to mysqli_stmt::bind_param() expected to be a reference, value given". The reflection class throws an exception. Other import sets using this code work just fine. Parameter 41 is the last parameter. Changing the affected code as follows resolves the issue:

<?php

$ref
= new \ReflectionClass("mysqli_stmt");
$method = $ref->getMethod("bind_param");
$data[count($data)-1] = (string) $data[count($data)-1];
$method->invokeArgs($stmtInsert, $data);
$stmtInsert->execute();

?>

Not sure what's going on here, but like I said, hopefully this will keep the next person from thinking they're totally insane.

<< Back to user notes page

To Top