PHP, MySQL & React REST API Tutorial with Example Form
Throughout this tutorial, we'll be using PHP with React and Axios to create a simple REST API application with CRUD operations. In the backend we'll use PHP with a MySQL database.
The PHP backend will expose a set of RESTful API endpoints so we'll be using the Axios library for making Ajax calls from the React.js UI.
We'll also see how to handle forms in React and how to send multipart form data with Axios using FormData.
In this tutorial, we are going to integrate React with PHP using Babel in the browser and a <script>
tag. As such, we'll serve the React application from PHP so we don't need to enable CORS in our server since both the backend and frontend are served from the same domain.
We'll see the other approach of using two separate servers for the frontend and backend apps in another tutorial which will use the create-react-app
to create the React project.
Prerequisites
You must have the following prerequsites in order to follow this tutorial comfortably:
- Knowledge of PHP and MySQL,
- Knowledge of JavaScript and React,
- PHP and MySQL installed on your development machine.
Creating the MySQL Database
Let's start by creating a MySQL database using the MySQL client (this usually gets installed when you install the MySQL server). Open a new terminal and run the following command:
mysql -u root -p
You'll be asked for your MySQL password. Make sure to submit the correct password and type Enter on your keyboard to confirm.
Next, you'll be presetend with the MySQL client CLI. You can create a database using the following SQL statement:
mysql> create database reactdb;
Next, let's add a SQL table in our database. Simpy run the following SQL instructions:
mysql> use reactdb;
mysql> CREATE TABLE `contacts` (
`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`city` varchar(100),
`country` varchar(100),
`job` varchar(100)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
We first run the use
SQL instruction to select the reactdb
database as our current working database. Next, we invoke the CREATE TABLE <name_of_table>
statement to create a SQL table that has the following columns:
- id: A unique identifier for the person,
- name: The name of the person,
- email: The email for the person,
- city: The city of the person
- country: The country of the person
- job: The job occupied by the person
Basically, this is a simple database for managing your contacts data.
Creating The PHP & MySQL RESTful API
After creating the MySQL database, table and columns. Let's now proceed to create a RESTful API interface exposed by a PHP application that runs CRUD operations against our previously-created MySQL table. Head back to your terminal and start by creating a directory for your project's files:
$ cd ~
$ mkdir php-react-rest-api-crud
Create a REST API Endpoint
Now, let's create an endpoint that provides contacts data in a JSON format to our Vue frontend.
Create an api
folder inside your project's root folder:
$ mkdir api
Navigate inside the api
folder and create a contacts.php
file and add the following content:
<?php
$host = "localhost";
$user = "root";
$password = "YOUR_MYSQL_DB_PASSWORD";
$dbname = "reactdb";
$id = '';
$con = mysqli_connect($host, $user, $password,$dbname);
$method = $_SERVER['REQUEST_METHOD'];
$request = explode('/', trim($_SERVER['PATH_INFO'],'/'));
if (!$con) {
die("Connection failed: " . mysqli_connect_error());
}
switch ($method) {
case 'GET':
$id = $_GET['id'];
$sql = "select * from contacts".($id?" where id=$id":'');
break;
case 'POST':
$name = $_POST["name"];
$email = $_POST["email"];
$country = $_POST["country"];
$city = $_POST["city"];
$job = $_POST["job"];
$sql = "insert into contacts (name, email, city, country, job) values ('$name', '$email', '$city', '$country', '$job')";
break;
}
// run SQL statement
$result = mysqli_query($con,$sql);
// die if SQL statement failed
if (!$result) {
http_response_code(404);
die(mysqli_error($con));
}
if ($method == 'GET') {
if (!$id) echo '[';
for ($i=0 ; $i<mysqli_num_rows($result) ; $i++) {
echo ($i>0?',':'').json_encode(mysqli_fetch_object($result));
}
if (!$id) echo ']';
} elseif ($method == 'POST') {
echo json_encode($result);
} else {
echo mysqli_affected_rows($con);
}
$con->close();
We first use the MySQLi PHP extension to create a connection to our MySQL database using the mysqli_connect()
method. Next, we use the $_SERVER['REQUEST_METHOD']
to retrieve the request method sent from the Axios client. If the request is GET, we create a SQL SELECT
query. if the request is POST we create a SQL INSERT
query with the post data retrieved from the $_POST
object.
After that, we use the mysqli_query()
method to run the query against our database table either to get or create data. Finally we use the json_encode()
method to encode data as JSON data and send it to the client.
You can serve your PHP application using the following command from the root of your project:
$ php -S 127.0.0.1:8080
Create the React App
Next, navigate to the project's root folder and add an index.php
file:
$ touch index.php
Next, open the index.php
file and add the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>PHP| MySQL | React.js | Axios Example</title>
<script src= "https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src= "https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- Load Babel Compiler -->
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
</body>
</html>
We simply include the React, ReactDOM, Babel and Axios libraries from their CDNs.
Next, in the index.html
, in the <body>
tag add a <div>
tag where you can mount your React application:
<div id='root'></div>
Next, add a <script>
tag of the text/babel
type to create our React app:
<body>
<div id='root'></div>
<script type="text/babel">
class App extends React.Component {
state = {
contacts: []
}
render() {
return (
<React.Fragment>
<h1>Contact Management</h1>
<table border='1' width='100%' >
<tr>
<th>Name</th>
<th>Email</th>
<th>Country</th>
<th>City</th>
<th>Job</th>
</tr>
{this.state.contacts.map((contact) => (
<tr>
<td>{ contact.name }</td>
<td>{ contact.email }</td>
<td>{ contact.country }</td>
<td>{ contact.city }</td>
<td>{ contact.job }</td>
</tr>
))}
</table>
</React.Fragment>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
</script>
</body>
We first create a React component called App
by extending the React.Component
class. Next, we add a contacts variable to the state
object which will be used to hold the contacts after we fetch them from the PHP REST endpoint using Axios.
Next, we define a React render()
method which returns a fragment that wraps the <h1>
header and <table>
elements.
In the table we loop through the this.state.contacts
and we display each <tr>
corresponding to each contact information.
Finally, we use the render() method of ReactDOM to actually mount our App
component to the DOM.
The contacts
array is empty. Let's use the Axios client to send a GET request to fetch data from /api/contacts.php
endpoint exposed by the PHP server.
In the App component add a componentDidMount()
life cycle method, which gets called when the component is mounted in the DOM, and inside it; add the code to fetch data:
componentDidMount() {
const url = '/api/contacts.php'
axios.get(url).then(response => response.data)
.then((data) => {
this.setState({ contacts: data })
console.log(this.state.contacts)
})
}
When data is fetched, we call the React setState method to update the state of the component with the fetched data.
Create a React Form for Submitting Data
Let's now add a React component that displays a form and handles submitting the form to the PHP backend. In your index.php
file add the following component before the App
component:
class ContactForm extends React.Component {
state = {
name: '',
email: '',
country: '',
city: '',
job: '',
}
handleFormSubmit( event ) {
event.preventDefault();
console.log(this.state);
}
render(){
return (
<form>
<label>Name</label>
<input type="text" name="name" value={this.state.name}
onChange={e => this.setState({ name: e.target.value })}/>
<label>Email</label>
<input type="email" name="email" value={this.state.email}
onChange={e => this.setState({ email: e.target.value })}/>
<label>Country</label>
<input type="text" name="country" value={this.state.country}
onChange={e => this.setState({ country: e.target.value })}/>
<label>City</label>
<input type="text" name="city" value={this.state.city}
onChange={e => this.setState({ city: e.target.value })}/>
<label>Job</label>
<input type="text" name="job" value={this.state.job}
onChange={e => this.setState({ job: e.target.value })}/>
<input type="submit" onClick={e => this.handleFormSubmit(e)} value="Create Contact" />
</form>);
}
}
Next include it in the App
component to be able to display it below the table:
class App extends React.Component {
// [...]
render() {
return (
<React.Fragment>
<!-- [...] -->
<ContactForm />
</React.Fragment>
);
}
}
Now let's change the handleFormSubmit()
of ContactForm
method to actually send the form data using Axios and FormData to our PHP REST endpoint which takes care of saving it in the MySQL database:
handleFormSubmit( event ) {
event.preventDefault();
let formData = new FormData();
formData.append('name', this.state.name)
formData.append('email', this.state.email)
formData.append('city', this.state.city)
formData.append('country', this.state.country)
formData.append('job', this.state.job)
axios({
method: 'post',
url: '/api/contacts.php',
data: formData,
config: { headers: {'Content-Type': 'multipart/form-data' }}
})
.then(function (response) {
//handle success
console.log(response)
})
.catch(function (response) {
//handle error
console.log(response)
});
}
Conclusion
In this tutorial, we've seen how to use PHP with MySQL, React and Axios to create a simple REST API CRUD example application. We have also seen how to handle forms in React and submit data to the server.
-
Date: