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

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

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!