MySQL with PHP
September 19, 2018
So far you have seen how PHP dynamically produces HTML (front-end). Now we will look at how PHP interacts with MySQL (back-end). You will learn how to connect to a database and execute data manipulation statements like INSERT, UPDATE and DELETE using PHP.
phpMyAdmin
phpMyAdmin is a free software tool written in PHP, intended to handle the administration of MySQL over the Web. It provides a user interface through which frequently used operations can be performed, while you still have the ability to directly execute any SQL statement. phpMyAdmin comes preinstalled with XAMPP.
When you installed XAMPP, you would have seen that the database that came along with it was called MariaDB and not MySQL. Both MariaDB and MySQL are very similar and can be used interchangeably. In fact, MariaDB is a fork of the MySQL open source project. This allows you to switch from MySQL to MariaDB (or vice versa) without having to alter your applications.
So let’s open up phpMyAdmin. Open a browser and go to http://localhost/phpmyadmin/
. You will see something like this:
Screenshot of phpMyAdmin
Creating Database and Table
Now we want to create a database and call it test
. Go to the left hand side column where it shows a list of default databases and click on the New
button.
To create a database, type in the database name as test
and click Create
.
Creating a database on phpMyAdmin
You will see that the test
database is now added to the list of available databases on the left. Click on test
and you will be able to create a table here. Let’s call it student
and set the number of columns to 3
and click on Go
.
Creating a table on phpMyAdmin
On this next page, you will be asked to specify the attributes for each of the 3 columns you want to create. Let’s see what these attributes are (we will focus on the important ones for now):
- Name: The name of the column.
- Type: Data type of the column. Popular types are
INT
(integer),VARCHAR
(character string),DATE
etc. - Length: The maximum length of the record in that column. It is generally used if the type is
VARCHAR
. ForINT
type, we don’t need to specify any length. - Index: If set to
PRIMARY
, the corresponding column becomes the primary key for the table. - A_I: Auto Increment. By default, the starting value for A_I is
1
, and it will increment by 1 for each new record. Often, we would like the primary key field to be created automatically every time a new record is inserted.
Now enter these details for each column of the student
table:
- For the first column, use the values Name =
id
, Type =INT
, Index =PRIMARY
. Check the box underA_I
(auto increment). - For the second column, Name =
name
, Type =VARCHAR
, Length =20
. - For the third column, Name =
marks
, Type =INT
.
Defining the columns of a table
Click on the Save
button.
Great! You just created a test
database and created a student
table with three columns: id
, name
and marks
using phpMyAdmin!
Insert
phpMyAdmin also allows us to execute SQL statements. Let’s write a query to insert data into the student
table that we just created.
First, click on the student
table under test on the left hand side. Then, on the top menu, choose SQL
. Here we will write our query:
INSERT INTO student (name, marks) VALUES ("Ana", 80)
Inserting values into a table using phpMyAdmin
Click on Go
. The row will be inserted and a message will be displayed:
1 row inserted.
Inserted row id: 1 (Query took 0.0591 seconds.)
Select
Now you can switch to the Browse
tab on the top menu to look at our first entry inside the student
table:
Selecting values from a table using phpMyAdmin
Update
We can easily update any entry in the table by simply double clicking on the field we want to update.
Updating values in a table using phpMyAdmin
Delete
We can delete a row by clicking on the Delete
button present in that row. Let’s delete the entry we just added. Click on the Delete button and you will see this popup message:
Deleting values from a table using phpMyAdmin
Click on OK
and your row will be deleted!
Note: We can select, update or delete rows of a table using the SQL query too (from the SQL tab in the top menu).
Now try messing around with the student
table by inserting, updating and deleting more rows and get comfortable with the phpMyAdmin tool!
Connecting to the database using PHP Data Objects (PDO)
So far, you saw how to execute basic SQL operations, and also how to perform these actions directly using the web interface of phpMyAdmin. Since phpMyAdmin is itself written in PHP, we can execute SQL operations using PHP directly as well!
First, we need to connect to the database. Create a file connection.php
with the following code:
<!-- connection.php -->
<?php
$dsn = 'mysql:host=localhost; dbname=test'; // database name
$user = 'root';
$pass = '';
try {
$pdo = new PDO($dsn, $user, $pass);
} catch(PDOException $e) {
echo 'Connection error! '. $e->getMessage();
}
?>
$dsn
refers to the database name - it includes two parameters, host
and dbname
. host
is set to localhost
while dbname
is set to the database we want to access (in this case test
).
The default username in MySQL is root
and the password is empty (if you installed it using XAMPP). We store these values in $user
and $pass
variables.
MySQLi vs PHP Data Objects
There are two popular methods work with a database in PHP:
- MySQLi extension (the “i” stands for improved)
- PDO (PHP Data Objects)
We will be using PDO (PHP Data Objects) in this course. PDO works on 12 different database systems, whereas MySQLi only works with MySQL databases.
Hence, if you need to switch your project to use another database, PDO makes the process easier. You only have to change the connection string and a few queries. With MySQLi, you will need to rewrite the entire code - queries included.
Okay, so let’s see what’s going on in our code.
To connect to the database using a PDO, we create an instance (object) of the PDO class (which is predefined in PHP) and pass the three arguments - $dsn
, $user
and $pass
.
$pdo = new PDO($dsn, $user, $pass);
If any of these values are incorrect - for example, if the database doesn’t exists, or the username password credentials are invalid - then an exception is thrown. Hence, we write this code in a try-catch block.
If an exception is thrown within the try
block, the script stops executing and flows directly to the catch()
block.
Go to your browser and open http://localhost/advanced/connection.php
. If the database connection was made and the $pdo
object got initialized, you will see a blank page.
Try changing the dbname
parameter to something which doesn’t exist:
$dsn = 'mysql:host=localhost; dbname=test1'; // database name
Now refresh the page and you will see an exception like this:
Connection error! SQLSTATE[HY000] [1049] Unknown database 'test1'
Awesome! You just learnt how to connect to the database using just PHP!
Data Manipulation using PHP Data Objects (PDO)
Finally, let’s look at how can we insert, select, update and delete values.
PHP Class corresponding to Database Table
For each table, we need to create a class which will have all methods corresponding to that table. For example, for the student
table, we will create a class called Student
which will have methods to insert, select, update and delete rows.
Create a file student.php
:
<!-- student.php -->
<?php
class Student {
protected $pdo;
function __construct($pdo) {
$this->pdo = $pdo;
}
}
?>
Here, we have declared a variable $pdo
with visibility set to protected
. We will pass the $pdo
database object to the constructor during initialization.
Before inserting new rows into the table using PHP, you might want to start fresh by deleting all records of the table
student
and setting the autoincrement value to 1 (it is not necessary though). This can be done running the query: `DELETE FROM student; ALTER TABLE student AUTOINCREMENT=1;`
Insert - Query Strings, bindParam() and execute()
To insert data into the student
table, let’s create a function insertStudent()
which accepts parameters $name
and $marks
.
<!-- student.php -->
<?php
class Student {
protected $pdo;
function __construct($pdo) {
$this->pdo = $pdo;
}
public function insertStudent($name, $marks) {
$stmt = $this->pdo->prepare("INSERT INTO student (name, marks) VALUES (:name, :marks)");
$stmt->bindParam(":name", $name, PDO::PARAM_STR);
$stmt->bindParam(":marks", $marks, PDO::PARAM_INT);
var_dump($stmt); // $stmt->execute();
}
}
?>
Here, $pdo->prepare()
function takes in the SQL statement and returns a Query String object. We don’t want to concatenate the values to the string using the .
operator as it will be vulnerable to SQL Injection. Instead, we will use a placeholder :
to bind the parameters.
This is done using the bindParam()
method, which takes three arguments: the placeholder name, the variable which we want to bind to the placeholder and the type of the data (PARAM_STR
refers to string and PARAM_INT
refers to integer).
Finally, we display the $stmt
object using var_dump()
. Later, we will replace this with $stmt->execute()
which will execute the SQL statement.
To call the function, let’s create another file and call it testsql.php
. This is the file we will be opening in our browser.
<!-- testsql.php -->
<?php
include "connection.php";
include "student.php";
global $pdo;
$student = new Student($pdo);
$student->insertStudent("Bob", 75);
?>
First, we include connection.php
and student.php
. Then, we declare a global variable $pdo
using the global
keyword. The $pdo
variable which was included via connection.php
file now has a global scope.
Then create an instance of the Student class and call the insertStudent()
function with the parameters Bob
and 75
.
Now, run the testsql.php
file and you should see the following output:
["queryString"]=> string(55) "INSERT INTO student (name, marks) VALUES (:name, :marks)"
Once we replace the var_dump()
statement with $stmt->execute()
, PHP binds the placeholders with the variables and the statement will be executed.
public function insertStudent($name, $marks) {
$stmt = $this->pdo->prepare("INSERT INTO student (name, marks) VALUES (:name, :marks)");
$stmt->bindParam(":name", $name, PDO::PARAM_STR);
$stmt->bindParam(":marks", $marks, PDO::PARAM_INT);
$stmt->execute();
echo "The statement has been executed!<br>";
}
Save the file and refresh the browser. You will see:
The statement has been executed!
Now open up phpMyAdmin and click on the student
table under the test
database. You will see the new row which just got inserted:
You just inserted a row to a table present in the MySQL database using only PHP! Isn’t this awesome?
Select - fetchAll(), fetch() and rowCount()
Let’s insert a couple more rows into the student table. Replace $student->insertStudent("Bob", 75)
in testsql.php
with these lines:
$student->insertStudent("Cathy", 90);
$student->insertStudent("Dave", 65);
Save and refresh the browser:
The statement has been executed!
The statement has been executed!
Check your phpMyAdmin to confirm that the 2 rows got inserted.
Say we want to display the names and marks of all the students. Let’s write a function displayAll()
:
public function displayAll() {
$stmt = $this->pdo->prepare("SELECT name, marks FROM student");
$stmt->execute();
$students = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach ($students as $student) {
echo '<h3>
'.$student->name.' '.$student->marks.'
</h3>';
}
}
Here, the fetchAll()
method returns an array of objects and each object has the columns that the SELECT
statement returned. The foreach
loop traverses each student object and displays $student->name
and $student->marks
.
Finally, call the function from testsql.php
.
<!-- testsql.php -->
<?php
include "connection.php";
include "student.php";
global $pdo;
$student = new Student($pdo);
$student->displayAll();
?>
Output:
Bob 75
Cathy 90
Dave 65
And that’s how you execute a SELECT statement using PHP and display the output!
You can use the fetch()
method to return only a single object instead of an array of objects.
Let’s write a function to fetch the marks of a student. We will pass the student name as an argument to the function.
public function getMarks($name) {
$stmt = $this->pdo->prepare("SELECT name, marks FROM student WHERE name = :name");
$stmt->bindParam(":name", $name, PDO::PARAM_STR);
$stmt->execute();
$student = $stmt->fetch(PDO::FETCH_OBJ);
echo $student->name . " scored " . $student->marks . " marks!<br>";
}
Call this function.
$student->getMarks("Dave");
Output:
Dave scored 65 marks!
You can also use the fetch()
method to do a count query, like so:
public function countStudents() {
$stmt = $this->pdo->prepare("SELECT COUNT(id) AS totalStudents FROM student");
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_OBJ);
echo $result->totalStudents;
}
Call this function.
$student->countStudent();
Output:
3
We can also call the rowCount()
method which returns the number of rows returned by the SELECT
statement. Let’s write a function to check if the student table is empty or not.
public function isEmpty() {
$stmt = $this->pdo->prepare("SELECT id FROM student");
$stmt->execute();
$count = $stmt->rowCount();
if ($count > 0) {
echo 'Some students found!';
} else {
echo 'No students found!';
}
}
Call the function.
$student->isEmpty();
Output:
Some students found!
Update and Delete
UPDATE
and DELETE
statements work similar to the INSERT
statement. Let’s create updateStudent()
and deleteStudent()
functions.
public function updateStudent($name, $marks) {
$stmt = $this->pdo->prepare("UPDATE student SET marks = :marks WHERE name = :name");
$stmt->bindParam(":name", $name, PDO::PARAM_STR);
$stmt->bindParam(":marks", $marks, PDO::PARAM_INT);
$stmt->execute();
}
public function deleteStudent($name) {
$stmt = $this->pdo->prepare("DELETE FROM student WHERE name = :name");
$stmt->bindParam(":name", $name, PDO::PARAM_STR);
$stmt->execute();
}
Call the functions.
$student = new Student($pdo);
$student->displayAll();
$student->updateStudent("Bob", 70);
$student->deleteStudent("Cathy");
echo 'After updating and deleting:<br>';
$student->displayAll();
Output:
Bob 75
Cathy 90
Dave 65
After updating and deleting:
Bob 70
Dave 65
Great! Now you can do everything directly from PHP that you could do with SQL!
Generic Insert, Update and Delete
In the previous section, you saw how to write PHP functions to insert, update and delete rows of a table. In general, instead of writing these functions for each table we have, we can write generic insert, update and delete functions.
It is a good practice to have one class representing each table in the database. Hence, we will write the insert, update and delete functions in a Base
class, and then have our table classes inherit from it. The generic functions will accept a table name and an associative array containing the key-value pairs that we want to insert or delete. For update queries, the generic function will also accept the id of the row which needs to be updated.
Here’s the code for base.php
:
<!-- base.php -->
<?php
class Base {
protected $pdo;
function __construct($pdo) {
$this->pdo = $pdo;
}
public function create($table, $fields = array()) {
// inserts a row into database table
$columns = implode(', ', array_keys($fields));
$values = ':' . implode(', :', array_keys($fields));
$sql = "INSERT INTO {$table} ({$columns}) VALUES ({$values})";
if ($stmt = $this->pdo->prepare($sql)) {
foreach ($fields as $key => $data) {
$stmt->bindValue(':'.$key, $data);
}
$stmt->execute();
return $this->pdo->lastInsertId();
}
}
public function update($table, $user_id, $fields = array()) {
// updates the row where id = $userid
$columns = '';
$i = 1;
foreach ($fields as $name => $value) {
$columns .= "{$name} = :{$name}";
if ($i < count($fields)) {
$columns .= ", ";
}
$i++;
}
$sql = "UPDATE {$table} SET {$columns} WHERE id = {$user_id}";
if ($stmt = $this->pdo->prepare("$sql")) {
foreach ($fields as $key => $value) {
$stmt->bindValue(':'.$key, $value);
}
$stmt->execute();
}
}
public function delete($table, $array) {
// deletes a row from database table
$sql = "DELETE FROM {$table}";
$where = " WHERE";
foreach ($array as $name => $value) {
$sql .= "{$where} {$name} = :{$name}";
$where = " AND ";
}
if ($stmt = $this->pdo->prepare($sql)) {
foreach ($array as $name => $value) {
$stmt->bindValue(':'.$name, $value);
}
}
$stmt->execute();
}
}
?>
In each of the three functions, we create the SQL query from the arguments!
There are only a couple of new things in the code above that you have not seen before.
- The
implode()
function returns a string from the elements of an array. For example,implode('-', ['one', 'two', 'three'])
is'one-two-three'
. - In the insert function, the id of the last inserted row is returned using the
lastInsertId()
method.
Using this generic code, accessing the database becomes even easier. We highly recommend saving this code for future use in projects.
Let’s see what the Student
class would look like given the Base
class.
Since we are declaring the $pdo
variable in the Base
class, we can remove it from the Student
class which now extends
the Base
class:
<!-- student.php -->
<?php
class Student extends Base {
function __construct($pdo) {
$this->pdo = $pdo;
}
// other functions go here...
}
?>
We need to include base.php
to our testsql.php
file:
<!-- testsql.php -->
<?php
include "connection.php";
include "base.php";
include "student.php";
global $pdo;
$student = new Student($pdo);
$student->create('student', array('name' => "Alice", 'marks' => 94));
$student->displayAll();
?>
Output:
Bob 70
Dave 65
Alice 94
Similarly, we can use the update and delete methods in this way:
$student->displayAll();
$student->update('student', 3, array('marks' => 88));
$student->delete('student', array('name' => 'Alice'));
echo 'After updating and deleting:<br>';
$student->displayAll();
Output:
Bob 70
Dave 65
Alice 94
After updating and deleting:
Bob 70
Dave 88
Easy, right? Now we don’t need the createStudent()
, updateStudent()
and deleteStudent()
methods in the Student
class.
Note: We did not create a generic
fetch()
function for SELECT statement as there are a lot of parameters for it likeCOUNT()
,ORDER BY
etc. However, if you see yourself repeating similar code again and again, you should think about writing a genericfetch()
function as well.
Summary
Okay, so in this tutorial you have learned about:
- phpMyAdmin: to perform operations in SQL using both the User Interface and SQL queries.
- PHP Data Objects: how to connect to the database using PHP, and how to perform fetch, insert, update and delete operations
- Generic insert, update and delete: Simple and handy PHP methods to perform SQL operations which can be reused for different database tables.
You made it this far! This is the most important tutorial in the course. Now you know how PHP works with both front-end as well as back-end.
You are now ready to create really cool websites with PHP! :)