Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : MySQL Improved Extension : mysqli_prepare

mysqli_prepare

Prepare a SQL statement for execution (PHP 5)
mysqli_stmt mysqli_prepare ( mysqli link, string query )

Example 1535. Object oriented style

<?php
$mysqli
= new mysqli("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
   
printf("Connect failed: %s\n", mysqli_connect_error());
   exit();
}

$city = "Amersfoort";

/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {

   
/* bind parameters for markers */
   
$stmt->bind_param("s", $city);

   
/* execute query */
   
$stmt->execute();

   
/* bind result variables */
   
$stmt->bind_result($district);

   
/* fetch value */
   
$stmt->fetch();

   
printf("%s is in district %s\n", $city, $district);

   
/* close statement */
   
$stmt->close();
}

/* close connection */
$mysqli->close();
?>

Example 1536. Procedural style

<?php
$link
= mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
   
printf("Connect failed: %s\n", mysqli_connect_error());
   exit();
}

$city = "Amersfoort";

/* create a prepared statement */
if ($stmt = mysqli_prepare($link, "SELECT District FROM City WHERE Name=?")) {

   
/* bind parameters for markers */
   
mysqli_stmt_bind_param($stmt, "s", $city);

   
/* execute query */
   
mysqli_stmt_execute($stmt);

   
/* bind result variables */
   
mysqli_stmt_bind_result($stmt, $district);

   
/* fetch value */
   
mysqli_stmt_fetch($stmt);

   
printf("%s is in district %s\n", $city, $district);

   
/* close statement */
   
mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);
?>

Code Examples / Notes » mysqli_prepare

adam

The purpose of prepared statements is to not include data in your SQL statements. Including them in your SQL statements is NOT safe. Always use prepared statements. They are cleaner to use (code easier to read) and not prone to SQL injections.
Escaping strings to include in SQL statements doesn't work very well in some locales hence it is not safe.


admin

Sorry for the typo it was performed on mysql 5.0 ofcourse.

codefiend
Note that single-quotes around the parameter markers _will_ prevent your statement from being prepared correctly.
Ex:
<?php
$stmt = $mysqli->prepare("INSERT INTO City (District) VALUES ('?')");
echo $stmt->param_count." parameters\n";
?>
will print 0 and fail with "Number of variables doesn't match number of parameters in prepared statement" warning when you try to bind the variables to it.
But
<?php
$stmt = $mysqli->prepare("INSERT INTO City (District) VALUES (?)");
echo $stmt->param_count." parameters\n";
?>
will print 1 and function correctly.
Very annoying, took me an hour to figure this out.


nom0ny

It must be noted in the Description whether developers should call mysqli_stmt_close prior to executing mysqli_prepare again on the same statement variable.
Example, Script A calls mysqli_stmt_close twice:
<?php
/* Script A -- We are already connected to the database */
$stmt = mysqli_prepare($link, "INSERT INTO table VALUES (?, ?, 100)"); /* Query 1 */
mysqli_stmt_bind_param($stmt, "si", $string, $integer);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); // CLOSE $stmt
$stmt = mysqli_prepare($link, "INSERT INTO table VALUES ('PHP', ?, ?)"); /* Query 2 */
mysqli_stmt_bind_param($stmt, "ii", $integer, $code);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); // CLOSE $stmt
/* Script A -- Continues on... */
?>
Next, we have Script B, calling mysqli_prepare again before issuing mysqli_stmt_close on the prior statement.
<?php
/* Script B -- We are already connected to the database */
$stmt = mysqli_prepare($link, "INSERT INTO table VALUES (?, ?, 100)"); /* Query 1 */
mysqli_stmt_bind_param($stmt, "si", $string, $integer);
mysqli_stmt_execute($stmt);
$stmt = mysqli_prepare($link, "INSERT INTO table VALUES ('PHP', ?, ?)"); /* Query 2 */
mysqli_stmt_bind_param($stmt, "ii", $integer, $code);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); // CLOSE $stmt
/* Script B -- Continues on... */
?>
Which method is more efficient and should be used by developers?


joe

in response to J dot andrew's   type function....
  switch ( gettype( $var ) ) {
           case 'integer':
               return 'i';
               break;
           case 'double':
               return 'd';
               break;
           case 'string':
               return 's';
               break;
           case 'boolean':
           case 'array':
           case 'object':
           case 'resource':
           case 'NULL':
           default:
                return NULL;
                break;
       } // could re-write to return first character, or remove breaks. Meh.
why do a string comparison?
you could do something like
if is_int($QueryVar)
$QueryVarType = "i";
elseif is_string($QueryVar)
$QueryVarType = "s";
elseif is_double($QueryVar)
$QueryVarType = "d";
else
die ("Invalid non-scalar value")


david kramer

I don't think these are good examples, because the primary use of prepared queries is when you are going to call the same query in a loop, plugging in different values each time.  For instance, if you were generating a report and needed to run the same query for each line, tweaking the values in the WHERE clause, or importing data from another system.

ulf wostner

Here is an example using bind_param and bind_result, showing iteration over a list of cities.
Note that there's some bug-potential in cases where the query returns NULL for some parameter value,
but the bind_result variables still might be bound.  So, we use a conditional to spray the spot first.
$mysqli->select_db("world");
$template = "SELECT District, CountryCode FROM City WHERE Name=?";
printf("Prepare statement from template: %s\n",  $template);
$cities = array('San Francisco', 'Lisbon', 'Lisboa', 'Marrakech', 'Madrid');
printf("Cities: %s\n", join(':', $cities));
if ($stmt = $mysqli->prepare($template)) {
  foreach($cities as $city) {
    // bind the string $city to the '?'
    $stmt->bind_param("s", $city);
    $stmt->execute();
    // bind result variables
    $stmt->bind_result($d,$cc);
    // 'Lisbon' is not found in the world.City table, but 'Lisboa' is.
    // Using a conditional we avoid putting Lisbon in California.
    if($stmt->fetch()) {
      printf("%s is in  %s, %s\n", $city, $d, $cc);
    }
  }
  $stmt->close();
}
With the conditional statement we get the desired result:
Prepare statement from template: SELECT District,CountryCode FROM City WHERE Name=?
Cities: San Francisco:Lisbon:Lisboa:Marrakech:Madrid
San Francisco is in  California, USA
Lisboa is in  Lisboa, PRT
Marrakech is in  Marrakech-Tensift-Al, MAR
Madrid is in  Madrid, ESP
But, without the conditional statement we would put Lisbon in California:
San Francisco is in  California, USA
Lisbon is in  California, USA
Lisboa is in  Lisboa, PRT
Marrakech is in  Marrakech-Tensift-Al, MAR
Madrid is in  Madrid, ESP


Change Language


Follow Navioo On Twitter
mysqli_affected_rows
mysqli_autocommit
mysqli_bind_param
mysqli_bind_result
mysqli_change_user
mysqli_character_set_name
mysqli_client_encoding
mysqli_close
mysqli_commit
mysqli_connect_errno
mysqli_connect_error
mysqli_connect
mysqli_data_seek
mysqli_debug
mysqli_disable_reads_from_master
mysqli_disable_rpl_parse
mysqli_dump_debug_info
mysqli_embedded_server_end
mysqli_embedded_server_start
mysqli_enable_reads_from_master
mysqli_enable_rpl_parse
mysqli_errno
mysqli_error
mysqli_escape_string
mysqli_execute
mysqli_fetch_array
mysqli_fetch_assoc
mysqli_fetch_field_direct
mysqli_fetch_field
mysqli_fetch_fields
mysqli_fetch_lengths
mysqli_fetch_object
mysqli_fetch_row
mysqli_fetch
mysqli_field_count
mysqli_field_seek
mysqli_field_tell
mysqli_free_result
mysqli_get_charset
mysqli_get_client_info
mysqli_get_client_version
mysqli_get_host_info
mysqli_get_metadata
mysqli_get_proto_info
mysqli_get_server_info
mysqli_get_server_version
mysqli_get_warnings
mysqli_info
mysqli_init
mysqli_insert_id
mysqli_kill
mysqli_master_query
mysqli_more_results
mysqli_multi_query
mysqli_next_result
mysqli_num_fields
mysqli_num_rows
mysqli_options
mysqli_param_count
mysqli_ping
mysqli_prepare
mysqli_query
mysqli_real_connect
mysqli_real_escape_string
mysqli_real_query
mysqli_report
mysqli_rollback
mysqli_rpl_parse_enabled
mysqli_rpl_probe
mysqli_rpl_query_type
mysqli_select_db
mysqli_send_long_data
mysqli_send_query
mysqli_server_end
mysqli_server_init
mysqli_set_charset
mysqli_set_local_infile_default
mysqli_set_local_infile_handler
mysqli_set_opt
mysqli_slave_query
mysqli_sqlstate
mysqli_ssl_set
mysqli_stat
mysqli_stmt_affected_rows
mysqli_stmt_attr_get
mysqli_stmt_attr_set
mysqli_stmt_bind_param
mysqli_stmt_bind_result
mysqli_stmt_close
mysqli_stmt_data_seek
mysqli_stmt_errno
mysqli_stmt_error
mysqli_stmt_execute
mysqli_stmt_fetch
mysqli_stmt_field_count
mysqli_stmt_free_result
mysqli_stmt_get_warnings
mysqli_stmt_init
mysqli_stmt_insert_id
mysqli_stmt_num_rows
mysqli_stmt_param_count
mysqli_stmt_prepare
mysqli_stmt_reset
mysqli_stmt_result_metadata
mysqli_stmt_send_long_data
mysqli_stmt_sqlstate
mysqli_stmt_store_result
mysqli_store_result
mysqli_thread_id
mysqli_thread_safe
mysqli_use_result
mysqli_warning_count
eXTReMe Tracker