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
28 Comments on "Say Hello To Angular 4 With PHP Backend [Angular 4 + PHP + MySQL]"
do you mind uploading the backend folder as well?
I’ve emailed you the back-end code. Hope that helps!
Please, emailed to me the back-end code too.
Thanks & regards from Spain.
Can you email me the backend code as well?
Hi Mohit, Can you email me the backend code as well?
Thank you very much! your post is the most helpful that i have found!
Glad that helped you 🙂
Could you add the php backend to your github?
Thanks!
Hi Mohit ,
Can you please send me the full code in my mail.
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…)
Your welcome!
It looks that you’re missing any configuration in PHP side. If the API calls successfully and insertion doesn’t work, you should debug in your PHP code.
It’s ok ! The problem was in the URL…
Hi Mohit ,
congratulations for this great and helpful post.
Can you please send me the full code in my mail, too.
Thanks
Thank you very much. they work like charm.
Can you suggest me the same functionality for Angular 5?
There’s no major difference with Angular 5 while developing it with PHP and MySQL.
You can do the installation by using Install Angular 5 [Hello World] article.
And then you can continue with the PHP.
where i put this folder php-rest-api in angular 4 directly
I sent you the back-end (PHP) code to your email id. You can put the PHP folder on the root folder of your project and just verify the path on API calls.
It’s very good. Could you please give me link for complete code or send me complete code??
The back-end (PHP) code is sent to your email.
I want backend hp code
Sent
Can you email me the back-end (PHP) code as well?
Sent
Could you please email me on the complete code if possible? Good Article.
Sent
Can you please send me backend code
Thanks
Sent