Say Hello To Angular 4 With PHP Backend [Angular 4 + PHP + MySQL]

32

After learning the basic examples of Angular 4, this article is dedicated to a simple Tutorial based on Angular 4 with PHP backend and eventually it will guide us to build an simple Angular 4 CRUD example with PHP MySQL.

As you know that, Angular is a front-end framework. So, we’d require a technology that handles the backend. For backend, we’re going to use PHP and MySQL for database.

Also, we already have taken the example of Angular 4 with Firebase To do and Angular 4 Firebase Authentication, this time we gonna explain a combination of Angular 4 + PHP + MySQL REST API example.

Getting Started: Angular 4 With PHP Backend

This example will basically build on frontend framework Angular 4 with PHP backend.

Here, we’re going to use MySQL as a database and create APIs in PHP that will communicate to the front-end which is built on Angular 4.

Also, we’re gonna use the Bootstrap 4 datatable, that is responsive, UI friendly and multiple purposes table.

So, let’s get started with how to use Angular 4 with PHP backend and build an Angular 4 CRUD example with PHP MySQL.

1. Install and Setup Angular 4 App

First of all, let’s create a simple Angular 4 app.

If you already have the Angular 4 app exists, you can skip this step. If not, you should visit and set up your First Angular 4 Hello World app.

Note: Here please make sure that you’re using an Angular CLI version which is 1.4.x.

You can check Angular CLI version using command shown below.

ng --version

Now, let’s create a new app using Angular CLI.

ng new angular4-crud-php-mysql

Related: Build Angular Apps Using Angular CLI

Now, you’re ready with the setup of your angular 4 app.

2. Install Bootstrap 4 In Angular 4 App

To install bootstrap 4 in our Angular 4 app, we need install the bootstrap 4 NPM package.

cd angular4-crud-php-mysql
npm install bootstrap@4.0.0-beta.2

Also, by using bootstrap 4 you’ll be able to perform or add other native bootstrap components like Alerts, Progressbar, Forms, Tables and many more.

Moreover, below command is used to install the dependencies.

npm install

Next, let’s add the bootstrap CSS in index.html

<!--In head section Bootstrap and Font awesome CSS-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

Now, there’re few more bootstrap 4 dependencies that require adding in index.html

<!--In head section-->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>

That’s it, now you’re ready to use Bootstrap 4 in your Angular 4 app.

3. Install Bootstrap 4 Datatable

Next, let’s install the bootstrap 4 datatable in our Angular 4 app.

npm install angular-4-data-table-bootstrap-4 --save

Next, we need to import DataTableModule and other needed dependencies in our main module to start using the datatable.

/src/app/app.module.ts

//Other dependencies..
import { CommonModule } from '@angular/common';
//Import form modules
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
//Import DataTable Module
import { DataTableModule } from 'angular-4-data-table-bootstrap-4';

Here, don’t forget to add these modules in import sections as well.

@NgModule({
	declarations: [
    	AppComponent
  	],
	imports: [
    	BrowserModule,
    	CommonModule,
		FormsModule,
		ReactiveFormsModule,
		DataTableModule
  	],
	providers: [],
  	bootstrap: [AppComponent]
})
export class AppModule { }

All set, to use DataTable in your app now.

Now, just run your app once, to make sure the everything works fine.

ng serve

Now, let’s move to the PHP backend side to structurize the APIs.

4. Use Angular 4 With PHP Backend + MySQL

Here, we’re going to design an Angular 4 CRUD example with PHP MySQL. For that, we’d require MySQL database and PHP backend code with REST API that can communicate with our Angular 4 app.

Note: Here, I assume that you already have installed Apache server, PHP and MySQL.

Also, I am going to create a separate folder with our backend code.

Design MySQL Database

First of all, design a simple MySQL database and table.

Let’s go to phpmyadmin and create a database with named angular4-crud.

And now fire the below query in your SQL console to design a simple table named users.

--
-- Database: `angular4-crud`
--
--
-- Table structure for table `users`
--
CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `first_name` varchar(255) NOT NULL,
  `last_name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `first_name`, `last_name`) VALUES
(19, 'ABC', 'ABC'),
(21, 'XYZ', 'XYZ'),
--
-- Indexes for dumped tables
--
--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=25;COMMIT;

Design PHP Backend With API

Here, we’re going to create a simple file that will interact with our Angular 4 app. And a class which will interact with the database and handle the CRUD operations.

/php-rest-api/index.php

This file will handle the requests and based on that call the database operations.

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    //If required
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 86400');    // cache for 1 day
}
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
 
	if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS");         
 
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
 
    exit(0);
}
// Connect to database
$conn = mysqli_connect('host','username','password','angular4-crud');

include_once('users.php');

$request_method = $_SERVER["REQUEST_METHOD"];

$data = json_decode(file_get_contents("php://input"));
$user = new Users;
switch($request_method)
{
	case 'GET':
		// Retrive Users
		if(!empty($_GET["user_id"]))
		{
			$user_id=intval($_GET["user_id"]);
			$user->getUsers($user_id);
		}
		else
		{
			$user->getUsers();
		}
		break;
	case 'POST':
		// Insert User
		$user->saveUser($data);
		break;
	case 'PUT':
		$user->updateUser($data);
		break;
	case 'DELETE':
		// Delete User
		$user->deleteUser($data);
		break;
	default:
		// Invalid Request Method
		header("HTTP/1.0 405 Method Not Allowed");
		break;
}

/php-rest-api/users.php

Users class will handles the database operations based on the call by index.php

<?php
class Users{
	//Get users
	function getUsers()
	{
		global $conn;
		$query="SELECT * FROM users ORDER BY id DESC";
		$response=array();
		$result=mysqli_query($conn, $query);
		while($row = mysqli_fetch_assoc($result))
		{
			$response[]=$row;
		}
		header('Content-Type: application/json');
		echo json_encode($response);
	}
	//Save user
	function saveUser($data){
		global $conn;
		$query="INSERT INTO users (first_name, last_name) VALUES ('".$data->first_name."', '".$data->last_name."')";
		echo $result=mysqli_query($conn, $query);
		header('Content-Type: application/json');
		//Respond success / error messages
	}
	//Update user
	function updateUser($data){
		global $conn;
		$query = "UPDATE users SET first_name='".$data->first_name."', last_name='".$data->last_name."' WHERE id=$data->id.";
		echo $result=mysqli_query($conn, $query);
		header('Content-Type: application/json');
		//Respond success / error messages
	}
	//Delete user
	function deleteUser($data){
		global $conn;
		$query = "DELETE FROM users WHERE id=".$data->id;
		echo $result=mysqli_query($conn, $query);
		header('Content-Type: application/json');
		//Respond success / error messages
	}
}

/php-rest-api/.htaccess

Now, we require .htaccess to hide the PHP extention from the URL.

RewriteEngine On

# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ https://www.thetechieshouse.com/php-rest-api/$1 [R=301,L]

# Redirect external .php requests to extensionless url
RewriteCond %{THE_REQUEST} ^(.+)\.php([#?][^\ ]*)?\ HTTP/
RewriteRule ^(.+)\.php$ https://www.thetechieshouse.com/php-rest-api/$1 [R=301,L]

# Resolve .php file for extensionless php urls
RewriteRule ^([^/.]+)$ $1.php [L]

Note: If you’re running PHP and Angular 4 app both on your localhost, you might get some difficulties of CORS enabled or 405 or 401. These StackOverflow proxy config and CORS Issue might help you.

Here we go, we’re all set with our PHP backend code.

5. Angular 4 CRUD Example with PHP MySQL

Now, let’s use the PHP APIs at Angular 4 app.

For that, as a good practice we should define an Angular 4 service that could handle the communication with PHP backend.

Define Angular 4 Service

Firstly, let’s create a service using Angular CLI.

ng generate service DbOperations

Now, let’s design the service that can handle API calls.

/src/app/db-operations.service.ts

//Import Injectable
import { Injectable } from '@angular/core';
//Import http modules
import {  Http, Response, Headers, RequestOptions } from '@angular/http';
//Import observable
import { Observable } from 'rxjs';
import 'rxjs/Rx';

@Injectable()
export class DbOperationsService {
	apiURL = "https://www.thetechieshouse.com/php-rest-api";
  	constructor(private http: Http){}
  	//Save users
	saveUsers(users: any[]){
		console.log(users);
		this.http.post(this.apiURL, users)
    	.subscribe(
        (val) => {
            console.log("POST call successful value returned in body", 
                        val);
        },
        response => {
            console.log("POST call in error", response);
        },
        () => {
            console.log("The POST observable is now completed.");
        });
	}
	//Get all users
	getUsers() {
		const headers = new Headers();

		headers.append("Cache-Control", "no-cache");
        headers.append('Access-Control-Allow-Origin', '*');
        headers.append('Access-Control-Allow-Methods', 'GET, POST');
        headers.append('Access-Control-Max-Age', '1728000');
		headers.append('Content-Type', 'application/x-www-form-urlencoded');
	    return this.http.get(this.apiURL);
	}
	//Update user
	updateUser(user)
	{
		return this.http.put(this.apiURL, user).subscribe(
        (val) => {
            console.log("UPDATE call successful value returned in body", 
                        val);
        },
        response => {
            console.log("UPDATE call in error", response);
        },
        () => {
            console.log("The UPDATE observable is now completed.");
        });
	}
	//Delete user
	deleteUser(user){
		return this.http.delete(this.apiURL, new RequestOptions({body : user
  		})).subscribe(
        (val) => {
            console.log("DELETE call successful value returned in body", 
                        val);
        },
        response => {
            console.log("DELETE call in error", response);
        },
        () => {
            console.log("The DELETE observable is now completed.");
        });
	}
}

Here, make sure that you’re importing service and other needed dependencies in your app main module.

/src/app/app.module.ts

//Import browser module
import { BrowserModule } from '@angular/platform-browser';
//Import core
import { NgModule } from '@angular/core';
//Import common
import { CommonModule } from '@angular/common';
//Import forms module
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
//Import DataTable
import { DataTableModule } from 'angular-4-data-table-bootstrap-4';
//Import HTTP for API call
import { HttpModule  } from '@angular/http';

//Import app component
import { AppComponent } from './app.component';
//Import service
import { DbOperationsService } from './db-operations.service';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    CommonModule,
    HttpModule,
	  FormsModule,
	  ReactiveFormsModule,
	  DataTableModule
  ],
  providers: [DbOperationsService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Now, we’re all set with our service to handle the API calls.

Next, let’s go and CRUD operations on Angular 4 with PHP backend.

List / Retrieve Operation

First of all, let’s define the app component and template to work with the CRUD operations.

/src/app/app.component.ts

Okay, so let’s import some dependencies in our app component.

After that, let’s have a class with few basic methods that help to render the data table.

//Import core modules
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
//Import forms modules
import { FormGroup, FormControl, Validators} from '@angular/forms';
//Import DataTable
import { DataTableResource } from 'angular-4-data-table-bootstrap-4';
//Import HTTP 
import {  Http, Response, Headers } from '@angular/http';

//Import DB service
import { DbOperationsService } from './db-operations.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
  	title = 'Angular 4 With PHP Backend [Angular 4 CRUD Example With PHP MySQL]';
  	userForm: FormGroup;
  	@ViewChild('modalClose') modalClose:ElementRef;
	persons: any[] = [];
	itemResource;
	items = [];
	itemCount = 0;
	params = {offset: 0, limit: 10}; //Static can be changed as per your need
	formFlag = 'add';

	constructor(private db:DbOperationsService, private http: Http){
		//DB service function called
	  	db.getUsers().subscribe(
	    	(response: Response) => { 
	    		this.persons = response.json();
	    		this.reloadItems(this.params);
	    	} ,
	    	(error) => {console.log(error);}
		);;
	}  

    reloadItems(params) {
		this.itemResource = new DataTableResource(this.persons);
		this.itemResource.count().then(count => this.itemCount = count);
	    this.itemResource.query(params).then(items => this.items = items);
    }

    // special properties:
    rowClick(rowEvent) {
        console.log('Clicked: ' + rowEvent.row.item.id);
    }

    rowDoubleClick(rowEvent) {
        alert('Double clicked: ' + rowEvent.row.item.id);
    }

	rowTooltip(item) { return item.jobTitle; }

	//Init method
	ngOnInit(){
		this.userForm = new FormGroup({
		  'id': new FormControl(null),
		  'first_name': new FormControl(null, Validators.required),
		  'last_name': new FormControl(null, Validators.required)
		});
	}

	initUser(){
		//User form reset
		this.userForm.reset();
		this.formFlag = 'add';
	}
}

/src/app/app.component.html

Let’s have a template with datatable and a form in modal popup that interact with users to get their inputs.

Also, we’ve used reactive form approach with validations.

<div style="margin: auto; max-width: 1000px; margin-bottom: 50px;">
  <div class="modal fade" id="add-edit-Modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h5 class="modal-title" id="exampleModalLabel">Add/Edit Form</h5>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">×</span>
          </button>
        </div>
        <form [formGroup]="userForm" (ngSubmit)="saveUser(formFlag)">
        <div class="modal-body">
          <input type="hidden" class="input-sm form-control" formControlName="id">
          <div class="form-group">
            <input type="text" class="input-sm form-control" formControlName="first_name">
            <p class="help-block" *ngIf="!userForm.get('first_name').valid && userForm.get('first_name').touched">Please enter first name.</p>
          </div>
          <div class="form-group">
            <input type="text" class="input-sm form-control" formControlName="last_name">
            <p class="help-block" *ngIf="!userForm.get('last_name').valid && userForm.get('last_name').touched">Please enter last name.</p>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" #modalClose data-dismiss="modal">Close</button>
          <button type="submit" class="btn btn-primary" [disabled]="!userForm.valid">Save changes</button>
        </div>
        </form>
      </div>
    </div>
  </div>

  <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#add-edit-Modal"  (click)="initUser()">Add</button>
  <data-table id="persons-grid"
    headerTitle="Angular 4 CRUD Example With Bootstrap 4 Datatable"
    [items]="items"
    [itemCount]="itemCount"
    (reload)="reloadItems($event)"

    (rowClick)="rowClick($event)"
    (rowDoubleClick)="rowDoubleClick($event)"
    [rowTooltip]="rowTooltip"
    >
    <data-table-column
        [property]="'first_name'"
        [header]="'First Name'"
        [sortable]="true"
        [resizable]="true"
        >
    </data-table-column>
    <data-table-column
        [property]="'last_name'"
        [header]="'Last Name'"
        [sortable]="true"
        >        
    </data-table-column>
    <data-table-column
      [property]="'Actions'"
      [header]="'Actions'">
      <template #dataTableCell let-item="item">
            <span style="color: rgb(232, 0, 0)">
            <a href="javascript:void(0);" (click)="getData(item)" data-toggle="modal" data-target="#add-edit-Modal">Edit</a>
            </span>
            <span style="color: rgb(232, 0, 0)">
            <a href="javascript:void(0);" (click)="delData(item)">Delete</a>
            </span>
      </template>
    </data-table-column>
  </data-table>
</div>

Also, don’t forget to mentioned your style for validations messages.

/src/app/app.component.css

input.ng-invalid.ng-touched {
	border: 1px solid red;
}
p.help-block{
	color: red !important;
}
.data-table-header{
	text-align: center !important;
}

Create / Add and Edit / Update Operations

Here, we’re using a same modal popup for add/edit operations by just switching it by using a formFlag.

Based on the flow, we’re performing the service method call and then update the view.

//Save user's data
saveUser(){
	if(this.formFlag == 'add')
	{
		this.userForm.value.id= this.persons.length + 1;
		this.persons.unshift(this.userForm.value);
		//Save method
		this.db.saveUsers(this.userForm.value);
	}
	else
	{
		//Update database
		this.db.updateUser(this.userForm.value);
		var index = this.persons.findIndex(x => x.id== this.userForm.value.id);
		if (index !== -1) {
		  this.persons[index] = this.userForm.value;
		}
	}
	this.reloadItems(this.params);
	//Close modal
	this.modalClose.nativeElement.click();
	//User form reset
	this.userForm.reset();
}
//Get data while edit
getData(item)
{
	//Here you can fetch data from database
	this.userForm.patchValue(item);
	this.formFlag = 'edit';
}

Delete Operation With DELETE Method

So, let’s implement the final delete operation.

Here, you can use the confirmation pop up as per your need.

//Delete user's data
delData(item){
	//Call service
	this.db.deleteUser(item);
        //Delete from array
	this.persons.splice(this.persons.indexOf(item), 1);
	this.reloadItems(this.params);
}

That’s it, you’re ready with an understanding of how to use Angular 4 with PHP backend and eventually it built an Angular 4 CRUD example with PHP MySQL.

Moreover, you can find the full code Angular 4 CRUD Example With PHP MySQL

Related: Angular 4 CRUD Example With Bootstrap 4 [Static Data – Without Database]

I hope, you loved this article. Feel free to share your questions by commenting below.

Final words, don’t forget to share this awesome tutorial on usage of Angular 4 with PHP Backend with your mates on below social media!

Leave a Reply

32 Comments on "Say Hello To Angular 4 With PHP Backend [Angular 4 + PHP + MySQL]"

avatar
  Subscribe  
newest oldest most voted
Notify of
ji
Guest

do you mind uploading the backend folder as well?

jing wen
Guest

Thank you very much! your post is the most helpful that i have found!

Travis
Guest

Could you add the php backend to your github?

Thanks!

suv
Guest

Hi Mohit ,
Can you please send me the full code in my mail.

Gwen
Guest

Thank you very much for this post !
I have a problem : the insertion doesn’t work when i click on the “add” button. However the message in the console is : “POST call successfull value returned in body” .
I don’t understand.
(Sorry for my english…)

huedda
Guest

Hi Mohit ,
congratulations for this great and helpful post.
Can you please send me the full code in my mail, too.
Thanks

NiKlause
Guest

Thank you very much. they work like charm.

Piyush
Guest

Can you suggest me the same functionality for Angular 5?

mahi
Guest

where i put this folder php-rest-api in angular 4 directly

Sunil
Guest

It’s very good. Could you please give me link for complete code or send me complete code??

Hemant
Guest

I want backend hp code

Rahul Mahindrakar
Guest

Can you email me the back-end (PHP) code as well?

Rahul Mahindrakar
Guest

Can you email me the back-end (PHP) code as well?

sfl
Guest

Could you please email me on the complete code if possible? Good Article.

Rushabh
Guest

Can you please send me backend code
Thanks

makaveli
Guest

Can you pls send me the backend code
and ty

Swathi
Guest

Can you please send me the backend code?