PHP Binding a Wildcard
Somebody asked me about how you bind a parameter in mysqli
when a multiple character wildcard needs to be next to the variable value. They’d found that it worked when creating a SQL statement by concatenation (string gluing), like this:
$sql = "SELECT item_title FROM item WHERE item_title LIKE '%".$title."%'"; |
However, they tried to bind the variable following the same pattern, and found that it failed. They used the following type of syntax:
$sql = "SELECT item_title FROM item WHERE item_title LIKE '%?%'"; |
It raised the following error:
Warning: mysqli_stmt_bind_param() [function.mysqli-stmt-bind-param]: Number of variables doesn't match number of parameters in prepared statement in program_name on line # |
The reason is the parser, it expects variables to be independent tokens in the SQL string. You can’t bind a string into the shell of an apostrophe delimited string. You could naturally, make an assignment to the local PHP variable before binding it to the variable, like this:
$title = '%'.$title.'%'; |
It’s actually a better idea to concatenate the multiple character wildcard operator inside the SQL statement. The correct syntax requires that you use the CONCAT()
function. You could reset to use piped concatenation but generally you should avoid that on the MySQL platform (see this post for an explanation of SQL concatenation on Oracle, MySQL, and SQL Server).
This is the required statement when using a MySQL database:
$sql = "SELECT item_title FROM item WHERE item_title LIKE CONCAT('%',?,'%')"; |
Complete Code Sample ↓
Expand this section to see the complete working code sample.
The first component for this program is an include file for the database credentials:
<?php // Connection variables. define('HOSTNAME',"localhost"); define('USERNAME',"student"); define('PASSWORD',"student"); define('DATABASE',"sampledb"); ?> |
Once you’ve placed the credentials in your directory, you can put this in the same directory and then call it from your browser. At least, you can provided you’ve created the user with the required password, and the database on the standard 3306
port.
<?php // Set database credentials. include_once("MySQLCredentials.inc"); // Return successful attempt to connect to the database. if (!$c = @mysqli_connect(HOSTNAME,USERNAME,PASSWORD,DATABASE)) { // Print user message. print "Sorry! The connection to the database failed. Please try again later."; // Assign the OCI error and format double and single quotes. print mysqli_error(); // Kill the resource. die(); } else { // Declare input variables. $title = (isset($_GET['title'])) ? $_GET['title'] : $title = "RoboCop"; query_insert($title); } // Query results afret an insert. function query_insert($title) { // Return successful attempt to connect to the database. if (!$c = @mysqli_connect(HOSTNAME,USERNAME,PASSWORD,DATABASE)) { // Print user message. print "Sorry! The connection to the database failed. Please try again later."; // Assign the OCI error and format double and single quotes. print mysqli_error(); // Kill the resource. die(); } else { // Initialize a statement in the scope of the connection. $stmt = mysqli_stmt_init($c); // Declare a SQL SELECT statement returning a CLOB. $sql = "SELECT item_title FROM item WHERE item_title LIKE CONCAT('%',?,'%')"; // Prepare statement. if (mysqli_stmt_prepare($stmt,$sql)) { mysqli_stmt_bind_param($stmt,"s",$title); // Execute it and print success or failure message. if (mysqli_stmt_execute($stmt)) { // Store result. mysqli_stmt_store_result($stmt); // Bind result to local variable. mysqli_stmt_bind_result($stmt,$item_title); // Open HTML table and print header. $out = '<table border="1" cellpadding="3" cellspacing="0">'; $out .= '<tr>'; $out .= '<th align="center" style="font-weight:bold;padding:2px;margin:1px;background:#8DB3E2;width:300px">Item Title</th>'; $out .= '</tr>'; // Read result. while (mysqli_stmt_fetch($stmt)) { $out .= '<tr>'; $out .= '<td style="padding:2px;margin:1px;background:#DBE5F1;">'.$item_title.'</td>'; $out .= '</tr>'; } // Close the HTML table. $out .= '</table>'; // Print the HTML table. print $out; } } // Free system resources. mysqli_stmt_free_result($stmt); // Disconnect from database. mysqli_close($c); } } ?> |