|
|
楼主 |
发表于 2011-8-4 14:17:00
|
显示全部楼层
Work With Prepared Statements
本帖最后由 Test 于 2011-8-4 14:27 编辑
Work With Prepared Statements
MySQL 4.1 introduced prepared statements to accomplish the task of executing a query repeatedly, albeit with different parameters in each iteration. Prepared statements can help increase security by separating SQL logic from the data being supplied. This separation of logic and data can help prevent a very common type of vulnerability called an SQL injection attack. However note that even though prepared statements can improve the security, it is still the responsibility of the application developer to guard against security attacks and to sanitize the input before submitting it to the database for processing.
Reduced query parsing due to the prepared statements can lead to significant performance improvements in the MySQL server.
The MySQL client/server protocol supports two methods of sending the database results to the client: as text and as binary. The text protocol always converts the data into strings before sending them across the network, and the server decodes the strings into appropriate data types. Unlike the text protocol, the binary protocol avoids converting the data into strings wherever possible. The binary protocol is used only with the prepared statements. Based on the data being sent over the network, the binary protocol that prepared statements use can reduce the CPU and network overhead by eliminating the encoding and decoding of the strings into the correct data types at the client and the server.
The following statements can be used as prepared statements: CALL, CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE, and most SHOW statements. See the latest MySQL Reference Manual to check the support for additional statements.
There are two types of prepared statements: bound-parameter prepared statements, and bound-result prepared statements. Bound-parameter prepared statements allow you to store a query statement on the MySQL server with only the changing data being repeatedly sent to the server and integrated into the query for execution. Similarly, bound-result prepared statements bind the results from a query to a set of PHP variables.
You can use the mysqli_stmt::bind_param() method of ext/mysqli to bind application variables to a prepared statement as parameters and mysqli_stmt::bind_result() to bind the results from a prepared statement to a set of PHP application variables.
The following example uses the bound-parameter as well as bound-result prepared statements to insert a couple of records into the City table of the test database, and then retrieves the result set by binding the PHP variable $city to the CityName field in the SQL statement.
- bash# cat PHPmysqliPreparedStmtsClient.php
- <?php
- /* create a new server connection */
- $cxn = new mysqli("localhost", "root", "admin", "test")
- or die ('Could not connect to the database server' . mysqli_connect_error());
- /* create the query and the corresponding placeholders */
- $sql = 'INSERT INTO City VALUES(?)';
- /* create a statement object */
- $stmt = $cxn->stmt_init();
- /* prepare the statement for execution */
- $stmt->prepare($sql);
- /* bind the parameters */
- $stmt->bind_param('s', $city);
- /* assign value to the $city parameter */
- $city = 'London, UK';
-
- /* execute the prepared statement */
- if ($stmt->execute()) {
- echo "\nSuccessfully inserted " . $city . " into the table, City.";
- }
- /* assign another value to the $city parameter */
- $city = 'Paris, France';
-
- /* execute the prepared statement one more time*/
- if ($stmt->execute()) {
- echo "\nSuccessfully inserted " . $city . " into the table, City.\n";
- }
- /* reclaim the statement resources */
- $stmt->close();
- /* create the query and the corresponding placeholders */
- $sql = 'SELECT CityName FROM City';
- /* create a statement object */
- $stmt = $cxn->stmt_init();
- /* prepare the statement for execution */
- $stmt->prepare($sql);
- /* execute the prepared statement */
- $stmt->execute();
- /* store the result */
- $stmt->store_result();
- echo "\nRetrieved " . $stmt->num_rows . " row(s).\n";
- /* bind the result parameters */
- $stmt->bind_result($city);
- echo "\nCityName\n--------\n";
- /* loop through the results and display the data */
- while($stmt->fetch()) {
- echo $city . "\n";
- }
- /* reclaim the statement resources */
- $stmt->close();
- /* close the database connection */
- $cxn->close();
- ?>
- bash# php PHPmysqliPreparedStmtsClient.php
- Successfully inserted London, UK into the table, City.
- Successfully inserted Paris, France into the table, City.
- Retrieved 5 row(s).
- CityName
- --------
- Hyderabad, India
- San Francisco, USA
- Sydney, Australia
- Paris, France
- London, UK
复制代码
Some of the important steps in the above code sample are explained below.
Instantiating the mysqli class via its constructor establishes a usable database connection to the MySQL server.
The mysqli::stmt_init() method initializes a statement and returns an object of type mysqli_stmt for use with mysqli_stmt::prepare().
Regardless of whether you are using the bound-parameter or bound-result prepared statement, first you need to prepare the statement for execution by using the mysqli_stmt::prepare() method.
Call the mysqli_stmt::bind_param() method to bind variable names to corresponding fields.
- bool mysqli_stmt::bind_param (string types, mixed &var1 [, mixed &varN])
复制代码
where the types parameter represents the data types of each respective variable to follow (represented by &var1, ... &varN in the syntax). At present, four type codes are supported:
- i for all INTEGER types
- d for the DOUBLE and FLOAT types
- b for the BLOB types
- s for all other types including strings
For example, if there are two variables and if the first variable is of type string and the second variable is of type integer, use the string "si" as the input for the types parameter.
The method mysqli_stmt::execute() executes a prepared statement.
The method mysqli_stmt::store_result() returns the result set from the prepared statement as a buffered set, meaning the entire set is made available for navigation immediately. Check the notes around the mysqli::store_result() method for the advantages and disadvantages of using buffered result sets.
The method mysqli_stmt::bind_result() binds columns in the prepared statement result set to PHP variables. In the above example, when mysqli_stmt::fetch() is called to fetch the data, the MySQL client/server protocol places the data for the bound columns into the specified variables $city.
Using mysqli_stmt::close() closes a prepared statement, and mysqli::close() closes the database connection.
Check the MySQLi Extension Function Summary page at PHP.net for the rest of the API that isn't discussed in this tutorial.
For More Information
Acknowledgments
Ulf Wendel, Sun | MySQL AB
|
|