Difference between revisions of "PHP and MySQL"
Line 15: | Line 15: | ||
$mysqli = new mysqli('localhost', 'username', 'password', 'databasename'); | $mysqli = new mysqli('localhost', 'username', 'password', 'databasename'); | ||
− | if( | + | if($mysqli->connect_errno) { |
− | + | printf("Connection Failed: %s\n", $mysqli->connect_error); | |
exit; | exit; | ||
} | } | ||
Line 50: | Line 50: | ||
$stmt = $myqli->prepare("insert into employees (first_name, last_name, department) values (?, ?, ?)"); | $stmt = $myqli->prepare("insert into employees (first_name, last_name, department) values (?, ?, ?)"); | ||
if(!$stmt){ | if(!$stmt){ | ||
− | + | printf("Query Prep Failed: %s\n", $mysqli->error); | |
exit; | exit; | ||
} | } | ||
Line 73: | Line 73: | ||
=== bind_param() === | === bind_param() === | ||
− | The most tricky line in the above example is the '''bind_param''' line. Here's how it works. | + | The most tricky line in the above example is the '''$stmt->bind_param()''' line. Here's how it works. |
The first parameter defines the data types of data to be inserted into the query. It is a string with one character per data type. The possible data types are: | The first parameter defines the data types of data to be inserted into the query. It is a string with one character per data type. The possible data types are: | ||
Line 86: | Line 86: | ||
The remaining parameters define values associated with each of the question marks in your query. | The remaining parameters define values associated with each of the question marks in your query. | ||
− | In the example code in the previous section, there are three question marks in the query, all of which are strings, and so the first argument to ''' | + | In the example code in the previous section, there are three question marks in the query, all of which are strings, and so the first argument to '''$stmt->bind_param()''' is 'sss'. The remaining three parameters is the information itself to be "injected" into the query. |
== Performing Queries that Return Data == | == Performing Queries that Return Data == | ||
Line 94: | Line 94: | ||
Consider the following example: | Consider the following example: | ||
− | <source lang="php"> | + | <source lang="php"><nowiki> |
<?php | <?php | ||
require 'database.php'; | require 'database.php'; | ||
− | $stmt = $mysqli->prepare("select first_name, last_name from employees"); | + | $stmt = $mysqli->prepare("select first_name, last_name from employees order by last_name"); |
+ | if(!$stmt){ | ||
+ | printf("Query Prep Failed: %s\n", $mysqli->error); | ||
+ | exit; | ||
+ | } | ||
+ | |||
$stmt->execute(); | $stmt->execute(); | ||
$stmt->bind_result($first, $last); | $stmt->bind_result($first, $last); | ||
+ | echo "<ul>\n"; | ||
while($stmt->fetch()){ | while($stmt->fetch()){ | ||
− | printf("%s %s\n", $first, $last); | + | printf("\t<li>%s %s</li>\n", |
+ | htmlspecialchars($first), | ||
+ | htmlspecialchars($last) | ||
+ | ); | ||
} | } | ||
+ | echo "</ul>\n"; | ||
$stmt->close(); | $stmt->close(); | ||
?> | ?> | ||
− | </source> | + | </nowiki></source> |
+ | |||
+ | Here, we use '''$stmt->bind_result()''' instead of '''$stmt->bind_param()''' because we are interested in the output from, not the input to, the query. | ||
+ | |||
+ | === bind_result() and fetch() === | ||
+ | |||
+ | Here, our query returns a table with two columns: first_name and last_name. So, we need to pass two parameters into '''$stmt->bind_result()''': one to store the first name, and one to store the last name. | ||
+ | |||
+ | After we call '''$stmt->bind_result()''', we call '''$stmt->fetch()'''. '''$stmt->fetch()''' stores the values from the next row in the result to the variables you specified in '''$stmt->bind_result()'''. '''$stmt->fetch()''' will continue binding rows into the variables until there are no rows left in the result set, at which time it will return null, thereby leaving the ''while'' loop. | ||
+ | |||
+ | '''Note:''' Use very unique variable names inside '''$stmt->bind_result()''', because whatever variables you use will be overwritten. This includes session variables, which are sometimes linked to the local variable of the same name. | ||
+ | |||
+ | === get_result() and fetch_assoc() === | ||
+ | |||
+ | If you do not want to bind the results from your query to variables, there is an alternative option that returns the results in arrays. | ||
+ | |||
+ | Consider this code: | ||
+ | |||
+ | <source lang="php"><nowiki> | ||
+ | <?php | ||
+ | require 'database.php'; | ||
+ | |||
+ | $stmt = $mysqli->prepare("select first_name, last_name from employees order by last_name"); | ||
+ | if(!$stmt){ | ||
+ | printf("Query Prep Failed: %s\n", $mysqli->error); | ||
+ | exit; | ||
+ | } | ||
+ | |||
+ | $stmt->execute(); | ||
+ | |||
+ | $result = $stmt->get_result(); | ||
+ | |||
+ | echo "<ul>\n"; | ||
+ | while($row = $result->fetch_assoc()){ | ||
+ | printf("\t<li>%s %s</li>\n", | ||
+ | htmlspecialchars( $row["first_name"] ), | ||
+ | htmlspecialchars( $row["last_name"] ) | ||
+ | ); | ||
+ | } | ||
+ | echo "</ul>\n"; | ||
+ | |||
+ | $stmt->close(); | ||
+ | ?> | ||
+ | </nowiki></source> | ||
+ | |||
+ | Instead of binding the columns of the result set to variables, they are returned in an associative array. '''$result->fetch_assoc()''' returns a new array for each row in the result set, and when there are no more rows, it returns null, thereby exiting the loop. | ||
+ | |||
+ | == Combined Queries == | ||
+ | |||
+ | You can also perform queries that both take input and produce output; you simply call both '''$stmt->bind_param()''' and '''$stmt->bind_result()'''. For example, the following selects all employees in the department specified in the GET variable '''dept''': | ||
<source lang="php"> | <source lang="php"> | ||
− | </ | + | <?php |
+ | require 'database.php'; | ||
+ | |||
+ | $dept = $_GET['dept']; | ||
+ | |||
+ | $stmt = $myqli->prepare("select first_name, last_name from employees where department=?"); | ||
+ | if(!$stmt){ | ||
+ | printf("Query Prep Failed: %s\n", $mysqli->error); | ||
+ | exit; | ||
+ | } | ||
+ | |||
+ | $stmt->bind_param('s', $dept); | ||
+ | |||
+ | $stmt->execute(); | ||
+ | |||
+ | $stmt->bind_result($first, $last); | ||
+ | |||
+ | echo "<ul>\n"; | ||
+ | while($stmt->fetch()){ | ||
+ | printf("\t<li>%s %s</li>\n", | ||
+ | htmlspecialchars($first), | ||
+ | htmlspecialchars($last) | ||
+ | ); | ||
+ | } | ||
+ | echo "</ul>\n"; | ||
− | + | $stmt->close(); | |
− | |||
− | + | ?> | |
</source> | </source> | ||
[[Category:Module 3]] | [[Category:Module 3]] |
Revision as of 20:02, 23 August 2012
MySQL is great, but it's not useful for web applications without a way to integrate it with your application logic. This article discusses how to query MySQL from within PHP.
This guide assumes that you already know how SQL queries are structured. If you don't, read MySQL Schema and State first. This guide also assumes that you have a working copy of MySQL. If you don't, read Introduction to MySQL also.
Contents
PHP Libraries for Database Manipulation
PHP comes with many different ways of querying databases. This guide instructs you on how to use MySQL Improved Prepared Statements, which is a cleaner, more elegant way to perform queries on your database.
Connecting to a MySQL Database in PHP
To connect to a database using the MySQL Improved interface, use the mysqli command:
<?php
$mysqli = new mysqli('localhost', 'username', 'password', 'databasename');
if($mysqli->connect_errno) {
printf("Connection Failed: %s\n", $mysqli->connect_error);
exit;
}
?>
You need to run this code before you can perform any other query on your database. Many PHP web developers put this code in a separate file and require it into other files that require database access.
You should create a new MySQL user with minimal privileges just for PHP to use.
Performing Queries that Require Parameters
When you want to INSERT or UPDATE an entry in your database, you probably need to supply some value from PHP for MySQL to interpret. This section discusses parameter binding, which is how you can do this sort of thing.
The first type of prepared query we will discuss are INSERT queries.
Suppose you had a form that submitted the following information:
- first, the user's first name
- last, the user's last name
- dept, the user's department
You could insert data received from the form into the employees database using the following PHP code:
<?php
require 'database.php';
$first = $_POST['first'];
$last = $_POST['last'];
$dept = $_POST['dept'];
$stmt = $myqli->prepare("insert into employees (first_name, last_name, department) values (?, ?, ?)");
if(!$stmt){
printf("Query Prep Failed: %s\n", $mysqli->error);
exit;
}
$stmt->bind_param('sss', $first, $last, $dept);
$stmt->execute();
$stmt->close();
?>
The query that will end up being executed by the above code is:
insert into employees (first_name, last_name, department) values ('John', 'Deere', 'EECE')
Notice how the MySQLi interface uses object-oriented PHP. Refer to the PHP guide if you need a refresher on object-oriented PHP.
bind_param()
The most tricky line in the above example is the $stmt->bind_param() line. Here's how it works.
The first parameter defines the data types of data to be inserted into the query. It is a string with one character per data type. The possible data types are:
- i - Integer
- d - Decimal
- s - String
- b - Blob
Note that data types in queries are not the same as data types in schemas. For instance, when saving a date into MySQL, you need to use a string representation of the data (except for timestamp, which uses an integer), so you would use the s option.
The remaining parameters define values associated with each of the question marks in your query.
In the example code in the previous section, there are three question marks in the query, all of which are strings, and so the first argument to $stmt->bind_param() is 'sss'. The remaining three parameters is the information itself to be "injected" into the query.
Performing Queries that Return Data
When you perform a successful SELECT query, MySQL always returns a table with the results of the query. This section discusses result binding, which is how you can load the result table into PHP.
Consider the following example:
<nowiki>
<?php
require 'database.php';
$stmt = $mysqli->prepare("select first_name, last_name from employees order by last_name");
if(!$stmt){
printf("Query Prep Failed: %s\n", $mysqli->error);
exit;
}
$stmt->execute();
$stmt->bind_result($first, $last);
echo "<ul>\n";
while($stmt->fetch()){
printf("\t<li>%s %s</li>\n",
htmlspecialchars($first),
htmlspecialchars($last)
);
}
echo "</ul>\n";
$stmt->close();
?>
</nowiki>
Here, we use $stmt->bind_result() instead of $stmt->bind_param() because we are interested in the output from, not the input to, the query.
bind_result() and fetch()
Here, our query returns a table with two columns: first_name and last_name. So, we need to pass two parameters into $stmt->bind_result(): one to store the first name, and one to store the last name.
After we call $stmt->bind_result(), we call $stmt->fetch(). $stmt->fetch() stores the values from the next row in the result to the variables you specified in $stmt->bind_result(). $stmt->fetch() will continue binding rows into the variables until there are no rows left in the result set, at which time it will return null, thereby leaving the while loop.
Note: Use very unique variable names inside $stmt->bind_result(), because whatever variables you use will be overwritten. This includes session variables, which are sometimes linked to the local variable of the same name.
get_result() and fetch_assoc()
If you do not want to bind the results from your query to variables, there is an alternative option that returns the results in arrays.
Consider this code:
<nowiki>
<?php
require 'database.php';
$stmt = $mysqli->prepare("select first_name, last_name from employees order by last_name");
if(!$stmt){
printf("Query Prep Failed: %s\n", $mysqli->error);
exit;
}
$stmt->execute();
$result = $stmt->get_result();
echo "<ul>\n";
while($row = $result->fetch_assoc()){
printf("\t<li>%s %s</li>\n",
htmlspecialchars( $row["first_name"] ),
htmlspecialchars( $row["last_name"] )
);
}
echo "</ul>\n";
$stmt->close();
?>
</nowiki>
Instead of binding the columns of the result set to variables, they are returned in an associative array. $result->fetch_assoc() returns a new array for each row in the result set, and when there are no more rows, it returns null, thereby exiting the loop.
Combined Queries
You can also perform queries that both take input and produce output; you simply call both $stmt->bind_param() and $stmt->bind_result(). For example, the following selects all employees in the department specified in the GET variable dept:
<?php
require 'database.php';
$dept = $_GET['dept'];
$stmt = $myqli->prepare("select first_name, last_name from employees where department=?");
if(!$stmt){
printf("Query Prep Failed: %s\n", $mysqli->error);
exit;
}
$stmt->bind_param('s', $dept);
$stmt->execute();
$stmt->bind_result($first, $last);
echo "<ul>\n";
while($stmt->fetch()){
printf("\t<li>%s %s</li>\n",
htmlspecialchars($first),
htmlspecialchars($last)
);
}
echo "</ul>\n";
$stmt->close();
?>