class file for com.google.android.gms.internal.zzbfm not found Firebase and Google maps – Solution

Today, we will share with you the solution for class “zzbfm” not found error while working on Firebase and Google maps.

If you are ever facing an error in android that says:

class file for com.google.android.gms.internal.zzbfm not found

It is most likely when you just integrated Firebase library in your project that is already using maps, location or places.

The solution to this is:

  1. Version number of google maps and Firebase should be same.
  2. Change “implementation fileTree” to “compileOnly fileTree”
  3. Enable multiDex and add multiDex library

app > build.gradle

android {
    compileSdkVersion 28
//    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "your.application.id"
        minSdkVersion 22
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        multiDexEnabled true // important
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
//    implementation fileTree(include: ['*.jar'], dir: 'libs')
    compileOnly fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.google.android.gms:play-services-maps:11.8.0'
    implementation 'com.google.android.gms:play-services-location:11.8.0'
    implementation 'com.google.android.gms:play-services-places:11.8.0'

    implementation 'com.google.firebase:firebase-core:11.8.0'
    implementation 'com.google.firebase:firebase-messaging:11.8.0'
    implementation 'com.google.firebase:firebase-database:11.8.0'

    implementation 'com.android.support:multidex:1.0.3'
}
apply plugin: 'com.google.gms.google-services'

build.gradle

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath 'com.google.gms:google-services:4.0.1'
    }
}

If your problem persists, please mention it in the comments section below. Check Google cloud platform for more services.

Learn how to embed maps without API key.

Maps without API Key – By Coordinates & By Address

Emoji ratings feedback – Javascript

Learn how to get feedback from your website users using emoji ratings. We will be using plain Javascript. No external library has been used in this tutorial.

Below is a list of all possible emojis at the time of writing this. You can found any new emoji missing, please do inform us in the comments section below.

SmileyHTML code
๐Ÿ˜€😀
๐Ÿ˜😁
๐Ÿ˜‚😂
๐Ÿ˜ƒ😃
๐Ÿ˜„😄
๐Ÿ˜…😅
๐Ÿ˜†😆
๐Ÿ˜‡😇
๐Ÿ˜ˆ😈
๐Ÿ˜‰😉
๐Ÿ˜Š😊
๐Ÿ˜‹😋
๐Ÿ˜Œ😌
๐Ÿ˜😍
๐Ÿ˜Ž😎
๐Ÿ˜😏
๐Ÿ˜😐
๐Ÿ˜‘😑
๐Ÿ˜’😒
๐Ÿ˜“😓
๐Ÿ˜”😔
๐Ÿ˜•😕
๐Ÿ˜–😖
๐Ÿ˜—😗
๐Ÿ˜˜😘
๐Ÿ˜™😙
๐Ÿ˜š😚
๐Ÿ˜›😛
๐Ÿ˜œ😜
๐Ÿ˜😝
๐Ÿ˜ž😞
๐Ÿ˜Ÿ😟
๐Ÿ˜ 😠
๐Ÿ˜ก😡
๐Ÿ˜ข😢
๐Ÿ˜ฃ😣
๐Ÿ˜ค😤
๐Ÿ˜ฅ😥
๐Ÿ˜ฆ😦
๐Ÿ˜ง😧
๐Ÿ˜จ😨
๐Ÿ˜ฉ😩
๐Ÿ˜ช😪
๐Ÿ˜ซ😫
๐Ÿ˜ฌ😬
๐Ÿ˜ญ😭
๐Ÿ˜ฎ😮
๐Ÿ˜ฏ😯
๐Ÿ˜ฐ😰
๐Ÿ˜ฑ😱
๐Ÿ˜ฒ😲
๐Ÿ˜ณ😳
๐Ÿ˜ด😴
๐Ÿ˜ต😵
๐Ÿ˜ถ😶
๐Ÿ˜ท😷
๐Ÿ™🙁
๐Ÿ™‚🙂
๐Ÿ™ƒ🙃
๐Ÿ™„🙄
๐Ÿค🤐
๐Ÿค‘🤑
๐Ÿค’🤒
๐Ÿค“🤓
๐Ÿค”🤔
๐Ÿค•🤕
๐Ÿค 🤠
๐Ÿคก🤡
๐Ÿคข🤢
๐Ÿคฃ🤣
๐Ÿคค🤤
๐Ÿคฅ🤥
๐Ÿคง🤧
๐Ÿคจ🤨
๐Ÿคฉ🤩
๐Ÿคช🤪
๐Ÿคซ🤫
๐Ÿคฌ🤬
๐Ÿคญ🤭
๐Ÿคฎ🤮
๐Ÿคฏ🤯
๐Ÿง🧐

Create input slider range

Create a div to display default emoji ratings, for example if you want the default feedback about communication to be “satisfied” then display the following emoji:

<div class="emoji-container">

<h3>Communication</h3>

<div class="emoji">
	๐Ÿ™‚
</div>

<p class="emoji-text">Satisfied</p>

<input type="range" name="status[communication]" min="0" max="4" step="1">
</div>

To view the emoji in large size, simply change the font size of emoji class. If you want to show the horizontal arrows for input type range, just change the cursor CSS property.

<style>
	.emoji {
		font-size: 60px;
	}
	input[type="range"] {
		cursor: ew-resize;
	}
</style>

Change emoji ratings with slider

Now create an array to store all type of emojis you want to display with your slider, and the meaning of each emoji in array of objects. Then we need to loop through all input type ranges and attach onmousemove listener to each slider.

Whenever the value of slider changes, we will get the emoji object using value of slider, and display it in emoji-container. This will replace emoji and its meaning text to whatever the value of current slider is.

If you are using only one slider in your document, you can use simply document.querySelector(“.emoji-container”) to get the container div of that emoji.

<script>
	var emojis = [
		{ emoji: "&#x1F621", text: "Hate it"},
		{ emoji: "&#x1F613", text: "Difficult to understand"},
		{ emoji: "&#x1F642", text: "Satisfied"},
		{ emoji: "&#x1F600", text: "Very happy"},
		{ emoji: "&#x1F618", text: "Loved it"}
	];

	var range = document.querySelectorAll("input[type='range']");
	for (var a = 0; a < range.length; a++) {
		range[a].onmousemove = function (event) {
			var index = this.value;
			var emojiContainer = this.closest(".emoji-container");

			emojiContainer.querySelector(".emoji").innerHTML = emojis[index].emoji;
			emojiContainer.querySelector(".emoji-text").innerHTML = emojis[index].text;
		};
	}
</script>

To save these feedback in database, enclose all your emoji-container divs in form tag and specify method as POST, and action to the file which will process this form data. If you sending input type file too, you also need to add an attribute enctype=”multipart/form-data” to form tag.

<form method="POST" action="save-feedback.php">
	<!-- All above emoji containers here -->
	<input type="submit">
</form>

Save data in database

We have created a simple database named tutorials and a table named feedback. It just has three columns, communicationservice and support. The data type of these columns will be INTEGER as in database we just be saving ratings on a scale of 1 to 5. First parameter in $_POST array will be name of input type range, and second will be the associative index we have set. Here we are receiving 3 types of feedback from user. The insert query is pretty basic.

save-feedback.php

<?php

$conn = mysqli_connect("localhost", "root", "", "tutorials");

$communication = $_POST["status"]["communication"];
$service = $_POST["status"]["service"];
$support = $_POST["status"]["support"];

$sql = "INSERT INTO feedback(communication, service, support) VALUES('$communication', '$service', '$support')";
mysqli_query($conn, $sql);

echo "Done";

?>

Change the emoji using slider and hit the submit button. You will see a new row will be inserted in database with integer value in respective columns. These integer values will tell the user feedback on a scale of 1 to 5.

Display on admin side

Now you might have an admin panel where you want to see the ratings given by user. So we will call a simple AJAX request to fetch those feedbacks from database. Our emojis array will remain same, and we can display the respective emoji based on database column value. First create an API page that will return all feedbacks in JSON format.

get-feedback.php

<?php

$conn = mysqli_connect("localhost", "root", "", "tutorials");

$sql = "SELECT * FROM feedback";
$result = mysqli_query($conn, $sql);

$data = array();
while ($row = mysqli_fetch_object($result))
{
	array_push($data, $row);
}
echo json_encode($data);

?>

Now back in index.php, we will send a simple AJAX request which will return all feedbacks in JSON string. We will parse that JSON into javascript arrays and objects. Create a div where all emojis needs to be displayed and display them using simple for loop.

<div id="feedback"></div>
var ajax = new XMLHttpRequest();
ajax.open("GET", "get-feedback.php", true);
ajax.send();

ajax.onreadystatechange = function () {
	if (this.readyState == 4 && this.status == 200) {
		var data = JSON.parse(this.responseText);
		var html = "";

		for (var a = 0; a < data.length; a++) {
			var communicationIndex = data[a].communication;
			var communication = emojis[communicationIndex];

			var serviceIndex = data[a].service;
			var service = emojis[serviceIndex];

			var supportIndex = data[a].support;
			var support = emojis[supportIndex];
				
			html += "<p>Communication: <span class='emoji'>" + communication.emoji + "</span>" + communication.text + "";

			html += "<p>Service: <span class='emoji'>" + service.emoji + "</span>" + service.text + "</p>";

			html += "<p>Support: <span class='emoji'>" + support.emoji + "</span>" + support.text + "</p>";
		}

		document.getElementById("feedback").innerHTML = html;
	}
};

Run this script on your admin panel and you will be able to view the user added feedback in emoji ratings and their meaning.

Learn how to calculate average ratings from here.

[wpdm_package id=’216′]

Multiple file upload in bootstrap modal – PHP & MySQL

We will teach you how you can create a bootstrap modal that handles multiple file upload and save them in MySQL database.

Download Bootstrap FileDialog

You are going to need a library called Bootstrap FD, you can get it from here. After downloading the library, extract the ZIP file and goto “dist” folder. Here you will find CSS and JS files, copy them in your project and include them in your header or footer. This library requires bootstrap and jQuery to be included in your project. If you have setup the bootstrap and jQuery, you can just use their CDN links rather than downloading.

<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>

<link rel="stylesheet" href="bootstrap.fd.css">
<script src="bootstrap.fd.js"></script>

First we have included the bootstrap CSS file, then jQuery and then bootstrap JS file. Because bootstrap JS also requires jQuery so you must include the jQuery before bootstrap JS. You can change the version number of CDN links if there is new version available.

Show multiple file upload dialog

Create a button which when clicked will call a function in Javascript. To open the bootstrap modal, we have to use the function $.FileDialog() and this will open the pop-up where you can drag and drop your files. For multiple file upload, we will not be using an input type file. But we will be using a library called FileDialog. You can also set options for this dialog, for example, whether you want the user to select only images files or all type of files etc.

<form>
	<button type="button" onclick="selectFiles();">
		Select files
	</button>

	<input type="submit">
</form>
<script>
	function selectFiles() {
		$.FileDialog({
			"accept": "image/*"
		})
	}
</script>

To preview the image files selected by user, just add a div tag and give it a unique ID.

<div id="selected-images"></div>

Preview selected images

And change your $.FileDialog function to the following. “files.bs.filedialog” function will be called when user select the files and press “OK”. Create a global array which will hold all images. All selected images will be received in “event.files” array, so loop through it and push in that global array. Create a string variable which will hold the img tag HTML. In the same loop, we are creating an img tag and each object of “event.files” array contains a variable named “content” while contains the content of image. This can be used.

window.selectedImages = [];

$.FileDialog({
	"accept": "image/*"
}).on("files.bs.filedialog", function (event) {
	var html = "";
	for (var a = 0; a < event.files.length; a++) {
		selectedImages.push(event.files[a]);
		html += "<img src='" + event.files[a].content + "'>";
	}
	document.getElementById("selected-images").innerHTML += html;
});

To save these images on server, give your form a unique ID and attach an onsubmit event with it. We will be using FormData object to send all images and other form fields via AJAX. And onsubmit event will prevent the default behaviour of form. This will prevent the form from submitting and will call your javascript function.

Call AJAX to upload file

This function will create a new FormData object and append all images in it. Make sure to add brackets “[]” with images key so it will send all images as array. Otherwise, only the last selected image will be processed by server. Then it sends a neat AJAX request in Vanilla JS and attach the form data in it.

After the server processed the files and send the response back to client, you will need to show some text to user or wants to redirect to different page. So in “onreadystatechange” event you can put all your code which needs to be executed once response is received from server.

<form id="form" onsubmit="return submitForm();">
function submitForm() {
	var form = document.getElementById("form");
	var formData = new FormData(form);

	for (var a = 0; a < selectedImages.length; a++) {
		formData.append("images[]", selectedImages[a]);
	}

	var ajax = new XMLHttpRequest();
	ajax.open("POST", "Http.php", true);
	ajax.send(formData);

	ajax.onreadystatechange = function () {
		if (this.readyState == 4 && this.status == 200) {
			console.log(this.responseText);
		}
	};

	return false;
}

Http.php

In this file, create a connection with your database (you might have already set up). Create a separate table where path of each image will be saved. Loop through all the images, insert them in database, and finally save the image file in your server. Create a new folder named “images” or any other of your choice, where all images will be stored. Timestamp is prepended with each image name just to make it unique. As you might have seen, if you download some image from facebook or whatsapp, it always has a different name no matter if that image is uploaded by another person.

<?php

$conn = mysqli_connect("localhost", "root", "", "tutorials");

for ($a = 0; $a < count($_FILES["images"]["name"]); $a++)
{
	$path = "images/" . time() . "-" . $_FILES["images"]["name"][$a];

	$sql = "INSERT INTO images(image_path) VALUES('$path')";
	mysqli_query($conn, $sql);

	move_uploaded_file($_FILES["images"]["tmp_name"][$a], $path);
}

echo "Done";

That’s how you can create a bootstrap modal that handles multiple file upload and save them in MySQL database in PHP.

Learn how to show progress bar while uploading the file.

[wpdm_package id=’213′]

Android cache SQLite

You can optimize your app performance by using cache data in Android using SQLite. We will be using Stetho library to see the cached data.

Basic use of cache in SQLite is to display frequently accessed data faster in your android app. And to reduce the overhead on the server. There are already tons of libraries available that automatically handles the API cache data for you. But nothing gives more control than writing the code by yourself. So in this tutorial, we will create a custom cache mechanism in SQLite. So we can decide when to expire the cache and which data needs to be cached in android system and which should not.

Volley default cache

By default, Volley does provide a method to cache the API response data. But it only caches the response which is already been received using Volley request. Consider this, you have a list of employee records which are being fetched from API. And then you have another API which receives employee ID and gives you detail about that employee. If you are using Volley’s cache mechanism then it only displays that employee data faster whose details you have already been seen. But using your custom technique, you can save all employees data in the SQLite cache. And get the detail of any employee using their ID.

1. Create an API

You might have your own API code based on your project, but for sake of this tutorial we have create a basic API which connects with database. Fetch all rows from employees table, push the data in an array and send the response back in JSON. We could have use the mysqli_fetch_all() function but it is not supported in some of the PHP versions. So following this technique you will be able to use this without having to worry about version of PHP.

<?php

$conn = mysqli_connect("localhost", "root", "", "classicmodels");
$result = mysqli_query($conn, "SELECT * FROM employees");

$data = array();
while ($row = mysqli_fetch_object($result))
{
    array_push($data, $row);
}
echo json_encode($data);

?>

Setup android project

We have created a new android project to demonstrate the working of SQLite cache. But you might be implementing this in your own project. So we will only discuss the libraries you need to install. And some minor settings you need to do in some of your project files. Open your app > build.gradle file and paste the following dependencies in it:

implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.volley:volley:1.1.1'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.facebook.stetho:stetho:1.5.1'

You can change the version number as per your project’s target SDK version. Android studio will highlight the dependencies if there is an update in Volley, Gson and Stetho libraries. After adding these dependencies, you need to sync the project. Then add internet permission in your AndroidManifest.xml file before starting of application tag. This will help you to call HTTP requests:

<uses-permission android:name="android.permission.INTERNET" />

Stetho library will be used to display SQLite inside google chrome inspect tools. Create a new class named MyApplication.java and extend it with Application:

package com.adnan.app.sqlitecache;

import android.app.Application;
import com.facebook.stetho.Stetho;

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Stetho.initializeWithDefaults(this);
    }
}

This will initialize the Stetho library and whenever you have some data in SQLite database tables, you will be able to see it by running chrome://inspect in your browser address bar (where you put website URL). Then set this class as application main class by giving name attribute to application tag in AndroidManifest.xml:

<application
        android:name=".MyApplication"

Setup layouts

Now we will setup the layout to create a recycler view where all employees data will be displayed. Also an adapter layout where each single employee data will be displayed. Create an adapter class which will hold each employee item, and a model class which tells the structure of data received from server. Create a recycler view in your activity layout file and get its instance in activity class file and initialize it.

EmployeeModel.java

package com.adnan.app.sqlitecache.models;

public class EmployeeModel {

    private String firstName;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
}

EmployeeAdapter.java

package com.adnan.app.sqlitecache.adapters;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.adnan.app.sqlitecache.R;
import com.adnan.app.sqlitecache.models.EmployeeModel;

import java.util.ArrayList;

public class EmployeeAdapter extends RecyclerView.Adapter {

    private Context context;
    private ArrayList models;

    public EmployeeAdapter(Context context, ArrayList models) {
        this.context = context;
        this.models = models;
    }

    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(context).inflate(R.layout.single_employee, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        viewHolder.name.setText(models.get(i).getFirstName());
    }

    @Override
    public int getItemCount() {
        return models.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView name;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            name = itemView.findViewById(R.id.name);
        }
    }
}

We are passing the activity context and models array from activity to adapter using adapter’s constructor. Context will help to setup the single layout file and models array helps to tell how many items should be rendered in this adapter and each item’s index.

single_employee.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_margin="20dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Name"
        android:id="@+id/name"/>

</RelativeLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rv" />

</RelativeLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
	private RecyclerView rv;
	private EmployeeAdapter adapter;
	private ArrayList models;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		rv = findViewById(R.id.rv);
		rv.setHasFixedSize(true);

		LinearLayoutManager layoutManager = new LinearLayoutManager(this);
		rv.setLayoutManager(layoutManager);

		models = new ArrayList<>();
		adapter = new EmployeeAdapter(this, models);
		rv.setAdapter(adapter);
	}
}

Get data from API

We will be using Volley library to send an HTTP request to API and fetch response as JSON string. Make sure you have added Volley dependency and synced the project. Also, make sure you have added internet permission in your android manifest. Create a new method in activity class and call it from onCreate method after the adapter has been set in recycler view.

private void getData() {
	String url = "Your API URL";
	RequestQueue requestQueue = Volley.newRequestQueue(this);

	StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
		@Override
		public void onResponse(String response) {
			Log.i("my_log", response);
		}
	}, new Response.ErrorListener() {
		@Override
		public void onErrorResponse(VolleyError error) {
			Log.i("my_log", error.getMessage());
		}
	});

	requestQueue.add(stringRequest);
}

Here our request method is GET and you can place your API URL in a variable named url. At this point, if you run the app in debug mode and open your logcat, you will be able to see the response after a few seconds (depends on the server and query execution time). If you saw any error in logcat, make sure you have added internet permission and double-check your API URL set in url variable.

This function will be called when the app is ran for the first time. Because for the first time, the android cache will empty since there is no data in SQLite database.

Mirror android to PC or Mac

Sometimes you might want to see your android device in your PC or Mac. You can use Vysor app which is available for both Mac and Windows, however, we do not recommend that because of too many pop-up ads. But we recommend to use the scrcpy library. You can install it from instructions on GitHub site and to run it, simply attach your android device and run the following command in your terminal:

> scrcpy

Convert JSON to ArrayList

We will be using Gson library to convert JSON string into Java array list. In onResponse of Volley request, create a try catch block because converting JSON to array will throw an exception if the data is not in correct JSON format. Even if you have any special character in your database, it will not be able to parse JSON data. We need to use the TypeToken class to convert json to array, if it were simple object then we would have simply used EmployeeModel.class but in case of array, we have to use TypeToken.

try {
	Gson gson = new Gson();
	Type type = new TypeToken<ArrayList<EmployeeModel>>() {}.getType();
	models = gson.fromJson(response, type);
} catch (Exception e) {
	Log.i("my_log", e.getMessage());
}

Filter data in adapter

Create a new method named showData() in activity and call it after the JSON has been converted into array list of models.

MainActivity.java

private void showData() {
	adapter.setFilter(models);
}

And in adapter add a new method which will remove old model data and add new data, and update the adapter to render the items again. The reason we are doing this is because at the time of assigning adapter to recycler view, our arraylist was empty. So if we do not use this method, then we will not be able to see any data in recycler view.

EmployeeAdapter.java

public void setFilter(ArrayList data) {
	this.models.clear();
	this.models.addAll(data);
	notifyDataSetChanged();
}

Show progress bar

If you want to display progress bar inside each adapter item, you can place this progress bar tag in your adapter layout file. This is typically useful when you are displaying images from HTTP, as they may take some time to display, so you can show a progress bar when the image is fully loaded. But here we will be displaying one progress bar in center of the screen, so we are creating progress bar tag in activity layout.

activity_main.xml

<ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:id="@+id/progressBar"/>

MainActivity.java

private ProgressBar progressBar;

// in onCreate after setContentView
progressBar = findViewById(R.id.progressBar);

// update showData method
private void showData() {
	adapter.setFilter(models);
	progressBar.setVisibility(View.GONE);
}

Setup SQLite

Create a new class named SQLiteManager and extend it from SQLiteOpenHelper. It has 2 abstract methods, onCreate and onUpgrade so you must implement them in your class. onCreate will be called only once, but onUpgrade will be called whenever you change your database version. Create a constructor for this class and call the super constructor, in super constructor we will tell the database name and version. In onCreate method, you will set your all tables structure (DDL). You can perform any function you want in onUpgrade method, but the common practice is, since we are upgrading the database version, it means that we may have remove some columns and have added some new columns, may be created a new table altogether. So the best practice is to remove all old tables structures and all data in them. Then call the onCreate method manually.

SQLiteManager.java

package com.adnan.app.sqlitecache.managers;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import com.adnan.app.sqlitecache.models.EmployeeModel;
import java.util.ArrayList;

public class SQLiteManager extends SQLiteOpenHelper {

    public SQLiteManager(Context context) {
        super(context, "android_cache", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE IF NOT EXISTS employees(" +
                "name TEXT NOT NULL)";
        db.execSQL(sql);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE employees");
        onCreate(db);
    }
}

Insert data in SQLite

Add the following method in your SQLiteManager class:

SQLiteManager.java

public void addData(EmployeeModel employeeModel) {
	SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
	ContentValues contentValues = new ContentValues();

	contentValues.put("name", employeeModel.getFirstName());
	sqLiteDatabase.insert("employees", null, contentValues);
	sqLiteDatabase.close();
}

Now in your activity class, in Volley onResponse method, when the JSON response has been converted to array list models, we will loop through all data in array and call this function for each employee. So create an instance of SQLiteManager class and initialize it and do the following:

MainActivity.java

private SQLiteManager sqLiteManager;

// in onCreate
sqLiteManager = new SQLiteManager(this);

// in Volley onResponse after models = gson.fromJson(response, type);
for (int a = 0; a < models.size(); a++) {
	sqLiteManager.addData(models.get(a));
}

This will add the data in SQLite database whenever we call an API request. But this will always append new data, so we need to find a way to delete old data whenever new data is received from API.

Delete data from SQLite

Create the following function in your SQLiteManager class:

SQLiteManager.java

public void deleteOldCache() {
	SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
	sqLiteDatabase.execSQL("DELETE FROM employees");
	sqLiteDatabase.close();
}

And call this function from your activity class:

MainActivity.java

// in Volley onResponse before for (int a = 0; a < models.size(); a++) and after models = gson.fromJson(response, type);
sqLiteManager.deleteOldCache();

View data from SQLite

At this point, the data has been saved correctly in SQLite. Now we need to make the app to read from SQLite database if there is any data, otherwise the data will be fetched from API. So the first time when app gets installed, it will not have any data in SQLite, so it will fetch from API and save in SQLite. Next time it will found the data, so it will read it from SQLite instead of sending the API request again.

SQLiteManager.java

public ArrayList getData() {
	ArrayList data = new ArrayList<>();
	SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
	Cursor cursor = sqLiteDatabase.rawQuery("SELECT * FROM employees", null);

	if (cursor.moveToFirst()) {
		do {
			EmployeeModel employeeModel = new EmployeeModel();
			employeeModel.setFirstName(cursor.getString(0));
			data.add(employeeModel);
		} while (cursor.moveToNext());
	}

	return data;
}

MainActivity.java

ArrayList cache = sqLiteManager.getData();

if (cache.size() > 0) {
	models = cache;
	showData();
} else {
	getData();
}

Now it will only fetch the data from API once and saved it in SQLite. Next time it will fetch from SQLite rather than from API. But the only problem is, it will always fetch it from SQLite. So we need to find a way to expire the cache after some time.

Set cache expiry time

You can set the expiry time of cache in simple seconds and you can do the math of converting seconds into minutes and hours and days etc. For example, if you want to expire the cache after 18 hours, you can simply do (60 * 60 * 18 = 64800). We will be using android shared preferences to store the time when data was cached or saved in SQLite. Then before checking if to get data from cache or from API, we need to check if the cache has been expired. We can do that by taking the difference between current time and the time when data was cached. Since Java date function returns time in milliseconds, so we can simply convert them to seconds by dividing them with 1000. Then our condition will say:

Check if there is any data in cache AND the cache is not expired.

MainActivity.java

private SharedPreferences preferences;

// in onCreate
preferences = PreferenceManager.getDefaultSharedPreferences(this);

boolean isCacheExpire = false;
long cacheTime = preferences.getLong("cache", 0);

if (cacheTime > 0) {
	long currentTime = new Date().getTime();
	long difference = currentTime - cacheTime;
	long seconds = difference / 1000;

	if (seconds > 20) {
		isCacheExpire = true;
	}
}

if (cache.size() > 0 && !isCacheExpire) {
	models = cache;
	showData();
} else {
	getData();
}

And set the cache time in shared preference in Volley onResponse method, after data has been saved in SQLite:

preferences.edit().putLong("cache", new Date().getTime()).apply();

Complete MainActivity.java

package com.adnan.app.sqlitecache;

import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;

import com.adnan.app.sqlitecache.adapters.EmployeeAdapter;
import com.adnan.app.sqlitecache.managers.SQLiteManager;
import com.adnan.app.sqlitecache.models.EmployeeModel;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
    private RecyclerView rv;
    private EmployeeAdapter adapter;
    private ArrayList models;
    private ProgressBar progressBar;
    private SQLiteManager sqLiteManager;
    private SharedPreferences preferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar = findViewById(R.id.progressBar);
        sqLiteManager = new SQLiteManager(this);
        preferences = PreferenceManager.getDefaultSharedPreferences(this);

        rv = findViewById(R.id.rv);
        rv.setHasFixedSize(true);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        rv.setLayoutManager(layoutManager);

        models = new ArrayList<>();
        adapter = new EmployeeAdapter(this, models);
        rv.setAdapter(adapter);

        ArrayList cache = sqLiteManager.getData();
        boolean isCacheExpire = false;
        long cacheTime = preferences.getLong("cache", 0);

        if (cacheTime > 0) {
            long currentTime = new Date().getTime();
            long difference = currentTime - cacheTime;
            long seconds = difference / 1000;

            if (seconds > 20) {
                isCacheExpire = true;
            }
        }

        if (cache.size() > 0 && !isCacheExpire) {
            models = cache;
            showData();
        } else {
            getData();
        }
    }

    private void getData() {
        String url = "Your API URL here";
        RequestQueue requestQueue = Volley.newRequestQueue(this);

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener() {
            @Override
            public void onResponse(String response) {
                try {
                    Gson gson = new Gson();
                    Type type = new TypeToken<ArrayList<EmployeeModel>>() {

                    }.getType();
                    models = gson.fromJson(response, type);
                    sqLiteManager.deleteOldCache();

                    for (int a = 0; a < models.size(); a++) {
                        sqLiteManager.addData(models.get(a));
                    }

                    preferences.edit().putLong("cache", new Date().getTime()).apply();

                    showData();
                } catch (Exception e) {
                    Log.i("my_log", e.getMessage());
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("my_log", error.getMessage());
            }
        });

        stringRequest.setShouldCache(false);
        requestQueue.add(stringRequest);
    }

    private void showData() {
        adapter.setFilter(models);
        progressBar.setVisibility(View.GONE);
    }
}

Run the app now. And you are all set in implementing SQLite cache in your android app. We have used android SQLite to save the data in the cache. But you can also use android’s shared preferences if the data that needs to be cached is relatively small.

[wpdm_package id=’211′]

Show progress of download with remaining time – Javascript

Convert time to different timezones

Learn how to show progress of download with remaining time in Javascript. We will be creating a simple bootstrap progress bar.

There are multiple ways to download a file from some website. The easiest way is to simply put an anchor tag with a text “Download”. And give the download attribute. Set the hypertext reference to the file which needs to be download. When the user clicks on it, the file will be downloaded using default browser download manager or via IDM.

However, there are some scenarios where that technique will not help. Take an example of a file with a very large size i.e. 1GB or greater, or a user running on a slow internet connection. The chances are the file may get interrupted during the download. In this case, user might have to re-download the file again. Even if he is using IDM, if the link gets expired then IDM will not resume the file. Instead it will download the file again from start.

Download file inside the browser

The second approach is to download the file inside the browser, show progress of download using a progress bar to the user. When the file is completely downloaded, then show a button which when clicked, will save the file in the selected destination on his computer. In this way, the file will be saved in the computer in just a couple of seconds. Because the file was already been downloaded inside the browser.

There are many other reasons for implementing this technique. For example, you can show advertisements to users until the file gets downloaded. This will help you monetize your website as well.

Get file from server

First we are going to get the file from the server and make it available for download. So, create a button that when clicked when send an AJAX request and get the file from the server. Also, an anchor tag must be created which will give the hypertext reference to the file when completely download in the browser. Lastly, we will add a progress bar which will show the progress of download.

<button id="download-button">Download</button>

<a id="save-file">Save File</a>

<progress id="progress" value="0"></progress>

Now in javascript, first we attach an onclick listener to the button. And call an AJAX request to the file which needs to be downloaded.

<script>
    var fileName = "Archive.zip";

	document.querySelector('#download-button')
		.addEventListener('click', function() {
			request = new XMLHttpRequest();
			request.responseType = 'blob';
			request.open('get', fileName, true);
			request.send();

			request.onreadystatechange = function() {
				if(this.readyState == 4 && this.status == 200) {
					var obj = window.URL.createObjectURL(this.response);
					document.getElementById('save-file').setAttribute('href', obj);

					document.getElementById('save-file').setAttribute('download', fileName);
					setTimeout(function() {
						window.URL.revokeObjectURL(obj);
					}, 60 * 1000);
				}
			};
	});
</script>

First we are creating an AJAX object. Note that the response type must be “blob”. By default, AJAX response type is text but since we wanted the download-able file to be returned from AJAX so we must set the response type to “blob”. In open function, first set the method of ajax which will be GET, then the second parameter should be the complete path of file which needs to be downloaded. We have created a variable where you can place your dynamic value. The first parameter will tell that the request must be asynchronous.

send() in AJAX

send() function will send the request to download the file and onreadystatechange will be called multiple times whenever the state of request changes. For example, when the request sent, when the request received and when the response is sent from the server. Here the readyState having value 4 and status having value 200 indicates the completion of request.

When the response is successfully received, we know that the response will be a downloadable file. Basically it will return the URL from where the user can save the file in his computer. So we will create an object using that URL, we will be using Javascript built-in URL object and call the function createObjectURL and pass the response received from ajax. Note that this response is not a responseText variable which is a string.

When the object is created using that URL, we will simply assign that as hypertext reference to our anchor tag. We are also setting the download attribute to anchor tag which tells the browser that the hypertext link to this anchor tag should be made downloadable.

revokeObjectURL

Since the object is created inside the browser, so it is also occupying some space. We can free it’s allocated resources after a few seconds. For example, the average size of file is 1GB and the user downloads 6 or 7 files, but if you do not free the object resources, then it might end up taking a lot of space in memory of your browser. So we are freeing the resources after 60 seconds, and we need to call the revokeObjectURL function and pass the object variable in it.

Display download progress

Now we need to create a progress bar and a text which will show the download percentage in textual format. In the above step, you can see that we have already created a progress tag, now we also need to create a span tag which shows the progress in percentage.

<span id="progress-text"></span>

<script>
	var progress = document.getElementById("progress");
	var progressText = document.getElementById("progress-text");

	request.onprogress = function(e) {
		progress.max = e.total;
        progress.value = e.loaded;

        var percent_complete = (e.loaded / e.total) * 100;
    	percent_complete = Math.floor(percent_complete);

    	progressText.innerHTML = percent_complete + "%";
	};
</script>

In javascript, first we are getting both nodes (progress & span) in separate variables. AJAX also provides us a method to track progress in an event called onprogress, it will have an argument and it tells the total amount of data that needs to be transferred (the size of file) and the which is currently been transferred so far.

We will set the total amount of data as the maximum value for the progress bar. And it continually changes the value of progress bar to the amount of data being transferred. So you will see the progress bar gradually moves from left to right as the file gets downloaded. The speed of progress bar depends on the size of the file and your internet connection.

File download percentage

So the progress bar has been set, now we display the percentage of the file downloaded in numbers. As we have already created a span tag in HTML and a variable for it in javascript. So we just need to calculate the percentage and display in span tag. We can calculate the percentage of the file downloaded by dividing the file currently downloaded by total size of file. That will return the value in between 0 and 1, for example 0.841. Multiplying this by 100 will return in 84.1 which means that 84.1 percent file has been downloaded.

If you do not want to display the decimal points with it, you can call the floor method and it will return the integer value. Then we simply set this percentage in span tag and add the percentage sign with it too.

Display transfer rate

At this point, if you were downloading that file via IDM or browsers default download manager, you will be able to view the downloading speed of your file. So our next step is to show downloading speed too. Create a simple span tag and get it in javascript as we did earlier. To get the downloading speed, we have to apply some math on it.

<span id="download-progress-text"></span>

<script>
    var downloadProgressText = document.getElementById("download-progress-text");

document.querySelector('#download-button')
		.addEventListener('click', function() {
    var startTime = new Date().getTime();
//// previous code in download button click listener
});

    request.onprogress = function(e) {
        var duration = ( new Date().getTime() - startTime ) / 1000;
    	var bps = e.loaded / duration;
        var kbps = bps / 1024;
        kbps = Math.floor(kbps);

        downloadProgressText.innerHTML = kbps + " KB / s";
    };
</script>

Getting the download speed means we need to know how much KB of data is transferred in one second. Since we are getting downloaded data in bytes so we can convert that in kilo bytes by simply dividing by 1024. First we will get the duration since the file started downloading till now. We can get it by getting the difference between current time and start time. That will return the time in milliseconds, so we can convert that into seconds by dividing with 1000.

When we get the total duration of AJAX then we can get the bytes transferred per second by dividing the data currently transferred by this duration. Now we have the Bytes per second, we can simply convert that to KB by dividing with 1024. Since there are 1024 bytes in one KB. This value may also be in decimal points, so we will convert that into integer too by using the same Math.floor() function. Lastly, we have set this variable in span tag and also display KB/s as string in it.

Get remaining time of download

The algorithm to calculate the remaining time is pretty simple. We get the difference between total size of file and the file currently being downloaded, and divide that by amount of data downloaded in bytes per second. This gives the time in seconds. But we need to show it in minutes too. For example, if this returns 90 seconds, then we need to display it as 1 minute and 30 seconds.

request.onprogress = function(e) {
        ...

        var time = (e.total - e.loaded) / bps;
        var seconds = time % 60;
        var minutes = time / 60;

        seconds = Math.floor(seconds);
        minutes = Math.floor(minutes);

        progress.setAttribute("aria-valuemax", e.total);
        progress.setAttribute("aria-valuenow", e.loaded);
        progress.style.width = percent_complete + "%";
        progress.innerHTML = percent_complete + "%";

        downloadProgressText.innerHTML = kbps + " KB / s" + "<br>" + minutes + " min " + seconds + " sec remaining";
};

No need to create another span tag for it, we will display this data inside span we created for displaying transfer rate. We use the modulus operator to get the remaining seconds, and we apply that to 60 since there are 60 seconds in 1 minute. Similarly, we can divide the time to 60 and it returns the time in minutes since 60 seconds composed of 1 minute.

These seconds and minutes may also be in decimal points, so we convert them to an integer using Math.floor() function as above. Lastly, we are appending that along with KB/s and prepending a line break (<br>) for readability.

Abort ajax request

We can abort any AJAX request using simple abort() function from ajax object. So we are simply creating a button which when clicked will abort the ajax request and you will see that progress of download, text, seconds and minutes will be stopped.

<button onclick="request.abort();" type="button">Abort</button>

Conclusion

This tutorial does not include any external library like jQuery. So you should be able to apply this in your project without having to include any library. It only contains Vanilla JS.

Though we could have use the NetworkInformation API to check transfer rate but it does not support all browsers at the time of writing this. So we do not want you to implement this in your website. Then later find out that your users are having problem downloading the file ๐Ÿ™‚

We have tried to create this tutorial as simple and accurate as we can. But if you still find any problem on our side, please do not hesitate to get in touch with us.

[wpdm_package id=’209′]

How to create and read RSS feed for your website – PHP

RSS feed is formerly known as RDF Site Summary feed, now it stands for Really Simple Syndication. It is a form of web feed that allows other computer programs to fetch updates about the website. Programs known as RSS aggregators are created which reads the feed in XML format in a standardized way.

Examples

For example, if you are running an E-commerce site. Then creating an RSS feed will help visitors to view the latest products on your website. Similarly, if you are running a blog. Then your RSS feed will be about the latest posts that you have published on your blog.

RSS feeds are XML files, so they must follow all the standard formats of XML. That includes the special characters. If your feed has some special characters like a single or double quote, you need to convert them to HTML entities before publishing or updating your feed.

RSS aggregators

The programs or scripts that are used to read these feeds are known as RSS aggregators. They follow a specific pattern to read and display feeds to users. So you must follow the rules and proper tags of XML to reach the global audience. There are a lot of tags which can be used in RSS but the most common are title, description, link, language, image, url, category, copyright and author.

How to create an RSS feed

There are multiple ways to create an RSS feed for your website and different people adopt different ways, that’s okay. You can either create a button on the admin panel to generate feeds and export the XML file. Then you can upload it manually using your cPanel file manager. Or you can add a function that will create or update an XML file whenever you post something new on your website. We will be using the second technique in this tutorial.

Also, you will need to create a button on your website’s main page from where users can see your feeds. One common practice is to create an anchor tag in HTML that will redirect the user to that XML file. User can then add that RSS link in this RSS aggregator software. Then will automatically be notified when you upload something new on your website. and your RSS feed gets updated.

Standard format

The standard format of creating an RSS feed is:

<?xml version="1.0" ?>
<rss version="2.0">
    <channel>
        <title></title>
        <description></description>
        <language>en-US</language>
        <link>http://website.com/</link>

        <item>
            <title>Pont Yacht
            <description>Measures 38 inches Long.</description>
            <link>http://website.com/prod.php?id=3212</link>
        </item>
    </channel>
</rss>

You can display as many item tags as you want but the format should remain the same. So copy and paste the following code in file where you want to generate your RSS feed. Typically whenever you post something new on your website.

<?php

$web_url = "http://" . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];

$str = "<?xml version='1.0' ?>";
$str .= "<rss version='2.0'>";
	$str .= "<channel>";
		$str .= "<title>My website</title>";
		$str .= "<description>My website</description>";
		$str .= "<language>en-US</language>";
		$str .= "<link>$web_url</link>";

		$conn = mysqli_connect("localhost", "root", "", "classicmodels");
		$result = mysqli_query($conn, "SELECT * FROM products ORDER BY productCode DESC");

		while ($row = mysqli_fetch_object($result))
		{
			$str .= "<item>";
				$str .= "<title>" . htmlspecialchars($row->productName) . "</title>";
				$str .= "<description>" . htmlspecialchars($row->productDescription) . "</description>";
				$str .= "<link>" . $web_url . "/product.php?id=" . $row->productCode . "</link>";
			$str .= "</item>";
		}

	$str .= "</channel>";
$str .= "</rss>";

file_put_contents("rss.xml", $str);
echo "Done";
?>

First we are creating a variable $web_url that will hold the base URL of the website. You can just set this variable a static value. But we are trying to make it dynamic so you won’t have difficulty when moving to different domains. Then we are creating a string variable $str that will hold all the RSS feed value in string format. We will be using this variable when creating an XML file.

<channel>

Channel tag will be served as a category since you might have different types of data on your website. So you can put different data in different channel tags. For example, you might have an E-commerce site and also the latest blog posts from one of your blog site.

Then we have title, description, link and url tags, they will be used to explain the properties of channel tag. The link must be your website’s main URL and language can be in one of the standard language codes. For getting website main URL we will be using PHP built-in SERVER variable and SERVER_NAME will return the name of the server which in this case will be localhost, and REQUEST_URI will return the address of folder from where this script is getting executed.

Then we are connecting with the database and fetching all the latest products in descending order (newest to oldest). You can see that we are using htmlspecialchars() function which helps to convert special characters into HTML entities. Since XML do not interpret special characters. So if you have any special characters and you are not using this function, then it might trigger an error in your RSS feed.

Saving XML file

Finally, we are calling file_put_contents() function which will create an XML file with the content of $str variable. If the file with same name already exists, it will simply update the file and override the previous content. Or if you are using Linux, make sure you have folder’s write permission in order to create that file.

If you run the script now you will be able to see a file named rss.xml created in your project’s root folder. You can drag that file in your browser, and you will see the feed in proper XML format. Now the last thing you can do is to display a link in your website which when clicked will redirect the user to this page.

Link to feed

We will be creating an anchor tag which when clicked will redirect the visitors to that XML file. We have also downloaded a logo of RSS from the internet. Instead of text we will be placing this image inside the anchor tag. Just copy and paste the following code anywhere in your website where you want to display a link to this RSS feed:

<a href="rss.xml" target="_blank">
	<img src="feed-icon.png" style="width: 100px;">
</a>

Since we want the feed to open in a new tab so it will not disrupt the user from using the site, so we have added an attribute target=”_blank” which will tell the browser to open that link in a new tab.

[wpdm_package id=’207′]

Use indexes to reduce the overhead on MySQL server

In MySQL database, indexes are used to optimize the database server by reducing the cost for searching data. Take it as an example of index page you see at the end of text books. It contains the page number of important words, so you do not have to check each page of the book to find that word. You just get the page number from index page, and directly lands on that specific page.

Same is the case with indexes in MySQL database. Indexes are applied on column level, so you can specify which values should be indexed. Generally, we apply indexes on those columns whose values are searched most often. For example, in user’s table, one might search for user by his email address. So we can apply the index on email address.

In this tutorial, we are using sample database called classicmodels and the table where we will be working is named as orderdetails. As discussed earlier, indexes are applied on column level, so we will be using column named productCode for this purpose. So let’s get started.

Get all indexes on table

The basic query of getting all indexes applied on some specific table is:

SHOW INDEX FROM table_name;

It will return name of index, sequence number of when applied, column name, integrity and collation etc. The output will be similar as screenshot above.

Even if you haven’t applied any index on any column of that table, you will still see indexes already applied on your table’s primary key (if you have any). They will be applied at the time of creation of table.

You can try running the query on productCode column using EXPLAIN alias and you will see the number of records MySQL server has to go through, just to fetch specific records.

EXPLAIN SELECT * FROM orderDetails WHERE productCode = "S18_3232";

In our case, the query has returned 53 records without applying EXPLAIN clause. And after applying EXPLAIN clause, it will tell that it has searched in 2996 records. So it is an overhead on MySQL server that it has to search in 2996 records just to pull 53 records. So we will be applying index on this column and you will see how much the query will be optimized.

Add index on column

You can either apply index by using ALTER statement or by CREATE INDEX, but we recommend using ALTER since it is been used by other DDL operations too, so it will be easier for you to remember. Also, ALTER helps you when deleting an index from table. Deleting index from column is also discussed at the end of this tutorial.

ALTER TABLE table_name ADD INDEX index_name (column_name);

In this statement, index_name can be anything of your choice. But make sure that it does not have any space and that index name must not be applied on any column before.

Check performance of query

As discussed earlier, we will be applying index on column named productCode. So suppose we have applied the index using the above query, and now we want to see the performance of our query.

After applying the index, you can run again the query but put EXPLAIN clause before the query. So you will performance of query. You will see that the number of rows fetched will be equal (or almost equal) to the number of rows MySQL server has seached.

In our case, MySQL server returned 53 rows using the above query. And the number of rows it has to go through is also 53. Your number may differ based on the size of your table and the query that you are testing.

Also, you will see the column named filtered in result of EXPLAIN query. That tells the percentage of data it has filtered between number of searched rows and number of rows in result.

Delete indexes from column

This will be almost similar to the add index section. You just need to replace the “ADD” with “DROP” and execute the query. In this query, you do not have to specify the name of column, just specify the name of index and it will be done.

ALTER TABLE table_name DROP INDEX;

Try running the show index query again and you will see that specific index will be removed from that column.

PHP PDO prepared statement – CRUD Operation

PHP PDO (PHP Data Objects) is basically an abstraction to database access, which means it is not limited to only MySQL or any other database system. If you are building a website in MySQL and suddenly you are required to change the database from MySQL to PostgreSQL, if you are using PDO at backend then only minor changes needs to be done in order to switch database. However, in other cases, you might have to re-write all the queries again in order to switch database.

PDO also provides a very neat way to write prepared statements which helps to prevent SQL injection in your database. In this tutorial, we will be performing completed CRUD (Create, Read, Update, Delete) operation using PHP PDO & MySQL. For sending data from forms, we will using AJAX so you also learn to fetch data from database without having to refresh the page.

Create data using PHP PDO prepared statement

First we will create a form from where we will get the input from user, and when user click the submit button, it will send an AJAX request with all form data. At the server end, server will first connect with our sample database called classicmodels using PDO. Then we will get all fields attached in AJAX request, prepare a query to prevent from SQL injection. Finally execute the query to add a new row in database.

You need to create a new file named save-data.php which will store the record in database. As this is an insert operation, so we might need the newly inserted ID on client side. So we can get the newly inserted ID by calling the $conn->lastInsertId() method from PDO connection object.

index.php

<form onsubmit="return addData();">
    <p>
        <input id="firstName" placeholder="Enter first name">
    </p>

    <input type="submit">
</form>

<script>
	function addData() {
        var firstName = document.getElementById("firstName").value;

        var ajax = new XMLHttpRequest();
        ajax.open("POST", "save-data.php", true);
        ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        ajax.send("firstName=" + firstName);

        ajax.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                console.log(this.responseText);
            }
        };

        return false;
    }
</script>

save-data.php

<?php

// Connecting with database
$conn = new PDO("mysql:host=localhost;dbname=classicmodels", "root", "");

// SQL query string
$sql = "INSERT INTO employees (firstName) VALUES(:firstName)";

// Preparing the statement
$result = $conn->prepare($sql);

// Actually executing the query in database
$result->execute(array(
	":firstName" => $_POST["firstName"]
));

// Sending inserted ID back to AJAX
echo $conn->lastInsertId();
?>

Remember that you should not write variables directly in SQL query string. You just have to mark the places where you wanted to put variables like :firstName. This will tell that we are going to map this with our variable later. Then in execute() function, you have to pass an array and map each string with corresponding variable.

Read data using PHP PDO prepared statement

Now that we have saved the data in database, now we need to display it to the user. First we will create table tag where we will display all records from database in tabular form. Then we will call an AJAX to request the server to pull records from database and return them as JSON. When data is returned from server, we will convert the JSON back to Javascript objects and display that in table rows and columns.

index.php

<table>
    <tbody id="data"></tbody>
</table>

<script>
	var ajax = new XMLHttpRequest();
	ajax.open("GET", "get-data.php", true);
	ajax.send();

	ajax.onreadystatechange = function () {
	    if (this.readyState == 4 && this.status == 200) {
	        var data = JSON.parse(this.responseText);

	        var html = "";
	        for (var a = 0; a < data.length; a++) {
	        	var id = data[a].employeeNumber;

	            html += "<tr>";
	                html += "<td>" + data[a].firstName + "</td>";
	            html += "</tr>";
	        }

	        document.getElementById("data").innerHTML += html;
	    }
	};
</script>

On server side, we will connect with database using PDO same way as we did for insert operation. When you are working on projects, make sure to use only one PDO object. You can do that by either using singleton objects or sending persistent attribute in PDO constructor after password field as below.

Using singleton

if ($conn == null)
{
	$conn = new PDO("mysql:host=localhost;dbname=classicmodels", "root", "");
}

Connect with database, execute the query to get all records from database. In this query, we are not using any variable input which is received from user, so no need to use prepared statement. But if you are required to use user input variable in query, you should follow the same method as we did for insert operation.

get-data.php

<?php

$conn = new PDO("mysql:host=localhost;dbname=classicmodels", "root", "", array(
	PDO::ATTR_PERSISTENT => true
));

$sql = "SELECT * FROM employees";
$result = $conn->query($sql);

echo json_encode($result->fetchAll());

?>

Adding persistent attribute in PHP PDO constructor will make your website faster by caching the connection. So the next time some script request for database connection, it will not create a new connection again but will return the cached connection. This will result in removing the overhead on database for making multiple connection on same database. Persistent connections are not closed at the end of script but will remain open for other scripts too.

Update data using PDO

Updating data consists of 3 parts.

  1. Create an edit button which when clicked will redirect to new page.
  2. Get all data of selected record from database and auto-populate that in form.
  3. Update the data in database when that form submits.

In your read operation AJAX where you are displaying data in table, add the below line inside the loop along with other <td> tags. This will redirect to edit page along with ID of selected record. That should be the unique ID in your table. We were already getting this ID variable in read operation.

index.php

html += "<td><a href='edit.php?id=" + id + "'>Edit</a></td>";

The code used for update operation is almost similar to the one we used for insert operation. First we will get the record from database using ID which we will be receiving from URL. User might temper that URL so we must bind that in prepared statement to prevent SQL injection.

The form will be similar to insert operation’s form, except we add a new hidden field for sending ID of selected record. It will also be appended in AJAX request. The rest will remains same.

edit.php

<?php

    $conn = new PDO("mysql:host=localhost;dbname=classicmodels", "root", "");

    $id = $_GET["id"];

    $sql = "SELECT * FROM employees WHERE employeeNumber = :id";
    $result = $conn->prepare($sql);
    $result->execute(array(
        ":id" => $id
    ));
    $data = $result->fetch();

?>

<form onsubmit="return editData();">
    <input type="hidden" id="id" value="<?= $id; ?>">
    <input id="firstName" placeholder="Enter first name" value="<?= $data["firstName"]; ?>">

    <input type="submit">
</form>

<script>
    function editData() {
        var firstName = document.getElementById("firstName").value;
        var id = document.getElementById("id").value;

        var ajax = new XMLHttpRequest();
        ajax.open("POST", "edit-data.php", true);
        ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        ajax.send("firstName=" + firstName + "&id=" + id);

        ajax.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                console.log(this.responseText);
            }
        };

        return false;
    }
</script>

Delete data using PDO

Deleting data consists of 2 parts.

  1. Create a delete button which when clicked will send an AJAX request.
  2. Server will run the delete query on selected record’s unique ID.

In your read operation AJAX where you are displaying data in table, add the below line inside the loop along with other <td> tags. This will call our Javascript function along with ID of selected record. That should be the unique ID in your table. We were already getting this ID variable in read operation.

A new function deleteData(id) will be created which will accept the ID of selected record and pass that ID with the AJAX request to the server.

index.php

html += "<td><button onclick='deleteData(\"" + id + "\")'>Delete</button></td>";

function deleteData(id) {
    if (confirm("Are you sure ?")) {
        var ajax = new XMLHttpRequest();
        ajax.open("POST", "delete-data.php", true);
        ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        ajax.send("id=" + id);

        ajax.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                console.log(this.responseText);
            }
        };
    }
}

Delete operation will be almost similar to update operation. You just create a prepared statement and map the ID which we are receiving from AJAX request and execute the query.

delete-data.php

<?php

$conn = new PDO("mysql:host=localhost;dbname=classicmodels", "root", "");

$sql = "DELETE FROM employees WHERE employeeNumber = :id";
$result = $conn->prepare($sql);
$result->execute(array(
	":id" => $_POST["id"]
));

echo "Done";

?>

If you want to delete the <tr> tag from <table> when the delete button is pressed, you need to give a custom data ID attribute to TR tag and call the remove() function to remove the TR node.

// In read operation AJAX loop
html += "<tr data-id='" + id + "'>";

// In deleteData() function
document.querySelector("tr[data-id='" + id + "']").remove();

So that’s the completed CRUD operation using PHP PDO & MySQL and AJAX. If you face any problem, feel free to ask in the comment’s section below.

[wpdm_package id=’203′]

Custom error handler – PHP

We will be craeting a custom error handler in PHP. As it name suggests, we will be displaying PHP errors in our own style.

Introduction

Error logs means to store a copy of an error that occurred in your website and saving it in a separate file. This helps you to keep track of all the errors in your website. By default PHP will display the error output on the screen. So if you are running a website on live server, it is always a good idea to keep track of any error, if happened.

For example, if a user perform some action that causes an logical error, so it causes a bug in your code. So you must know what and where that error occurred in your script. We can get the error code and the error code must be one of the following as mentioned in table. We can also get the error string which actually tells the error, for example, “undefined variable”, and file name which causes the error and also it’s line number.

Error levels

ValueConstantDescription
1E_ERRORFatal run-time error
2E_WARNINGRun-time warning
4E_PARSECompile-time parsing error
8E_NOTICEError in script/code
256E_USER_ERRORUser-generated error by calling trigger_error($error)
512E_USER_WARNINGUser-generated warning by calling trigger_error($error)
1024E_USER_NOTICECustom error
8192E_DEPRECATEDDeprecated code error
32767E_ALLAny type of error and warning

Following code will create a custom function and tells PHP to use this function instead of using built-in PHP error system. We will be storing logs for each day so the file name must be of today date. For this purpose, we are using PHP date($format) function to dynamically fetch today’s date. Then we are creating a variable to store error level, actual error, file name where error occurred and line number which causes the error.

We have echo the error so it will be visible in the browser, but can skip this line if you do not want to show the error to your users. We are using file_put_contents($filename, $content, $mode) function to save that error in file. You need to create a folder named logs where all error files will be saved. We will be using FILE_APPEND mode which will create a file if not exists, and append the data at the end of file if file of same name already exists.

PHP built-in error handler function

Finally we will call the set_error_handler($custom_function_name) function that tells the PHP to use custom function for handling errors. The parameter will be the name of function that we have just created, and it’s name must be in string. At the end, we have echo a variable which is not yet created, so it will trigger an error. We did this deliberately to generate an error.

<?php

// Create a custom error function
function on_error($error_no, $error, $filename, $linenumber)
{
	// get today date, saving logs for each day
	$today = date("Y-m-d");

	// Creating array for possible errors
	$error_levels = array(
		"1" => "Fatal error",
		"2" => "Warning",
		"8" => "Error",
		"1024" => "Custom error"
	);
	
	// Getting name of error by error level
	$str = $error_levels[$error_no] . ": ";

	// Display file name where error occurred
	$str .= $error . " in " . $filename;

	// Show line number which causes error
	$str .= " at " . $linenumber;

	// Moving to next line
	$str .= "\n";

	// Display error in browser
	// if you do not want to show errors to user,
	// then you can skip this line
	echo $str;

	// save the $str value in file
	file_put_contents("logs/" . $today . ".txt", $str, FILE_APPEND);
}

// Tells PHP to use custom function for errors
set_error_handler("on_error");

// Generating error deliberately
echo $a;

?>

If you are using Mac or Linux, you may also need to enable a folder to write permissions of the logs folder. That’s how you can create and use the custom error handler function in PHP and save errors in files as logs.

You can also enable all error reporting using default PHP functions:

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

In Javascript, you can catch all errors using the following code:

window.onerror = function (error, file, line) {
    alert(error + " at line " + line)
}

If you face any problems, feel free to ask in the comments section below.

[wpdm_package id=’201′]

Page level cache PHP

Page level cache in PHP means that the most frequent data will be stored in cache. So instead of requesting the same data from database, we will just use the cache to display that data. This will reduce the overhead on database by eliminating number of queries on SQL. Or any other database server you are using.

Cached data storage

Cached data will be stored in files. So it is advised not to store sensitive data, like passwords and credit cards, in the cache. Although no one will know by which name you have saved the cache. But in some circumstances, it can be readable. So we must save that data in a database which is not sensitive. And we can use page level cache in PHP without any fear.

Once data is cached in a file then whenever a user requests that data it will not be fetched from the database. Instead it will be fetched from the cache. This will decrease the page load time and hence will improve the performance of website. For example, if a database query took 6 seconds to fetch the data. Then using this technique you can skip those 6 seconds wait.

Expiry time of cached data

You can also set the expiry time of the cache. So if you have cached some data and now the user is seeing the data from cached files. Now, what if you made some changes in the database ? The user will still be seeing the old cached data ! That is where we need to set the expiry time of the cache. A common practice is to expire the cache after 24 hours but you can customize it as per your needs.

Display page load time

First, we need to find a way to check the actual page load time. So we can get the time when we were at 1st line of the page and we can get the time when we were at the last line of the page. Then we will get the difference between start and end time and we will know the number of seconds it takes to load the page.

<?php

$start_time = time();

?>

<?php

$end_time = time();
echo "<h1>Difference: " . ($end_time - $start_time) . " seconds</h1>";

Create cache

We set the name of the file where we want to store the cache. You can create a separate folder where all caches will be stored, most modern frameworks use this approach. We also will set the expiry time of the cache so it will fetch fresh data after a specified time period.

We will be using output buffering which is used to hold plain HTML before it is displayed in the browser. Whatever content is displayed between ob_start() and ob_get_contents() will be saved in the file.

Then we create a file using write mode and the content of the file will be plain HTML that is rendered on the webpage. So if you open the cache file, you will see that it will have all plain HTML (same as you see when you do “view page source”). That is why it is recommended not to save sensitive data like passwords and credit cards in the cache. Finally, we can close the file object and when you run the script now, you will be able to see a new file created with HTML content.

<?php

$cache_file = "cache.php";
$cache_time = 60; // 1 minute

// Start output buffering
ob_start();

// run all DB queries here

$file = fopen($cache_file, "w");
fwrite($file, ob_get_contents());
fclose($file);

Read cache

We will read the cache only if the file exists and it has not been expired. When you run the script the first time, then the file has not yet been created. So that means that you do not have any cache, after that we will check the expiry time of the cache using file modified time.

Now if the cache is found and it is not expired, then we will display the content from the cache instead of requesting from database. To read the file we have 2 options, one is to use the include or require function and the second is to use readfile function. However, readfile is more secure than include so we will be using this.

You can use else condition if you want to perform some other action, that depends on your needs. But for simplicity, we will stop the script after reading from the cache using the exit() function. Paste the following code after $cache_time variable and before ob_start() function.

<?php

$cache_time = 10; // seconds

if (file_exists($cache_file) && (filemtime($cache_file) + $cache_time > time()))
{
	readfile($cache_file);
	exit();
}

ob_start();

That’s it, now if you run the script you will see that when it loads from the database, it takes more time than when it does from the cache. The script is tested on multiple already created projects and by average it loads 5 seconds faster than using without cache.

Tired of clearing browser cache after making changes in CSS or JS files ?

Prevent browser cache from CSS, JS, and image files

[wpdm_package id=’199′]