Lazy load images means loading images on websites asynchronously. Lazy loading is technique that defers loading of non-critical resources at page load time. Instead, these non-critical resources are loaded at the moment of need. Where images are concerned, “non-critical” is often synonymous with “off-screen”. If you’ve used Lighthouse and examined some opportunities for improvement, you may have seen some guidance in this realm in the form of the Offscreen Images audit.
Intersection observer API
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document’s viewport.
We are going to use 2 images. One will be displayed on top and second will be at the bottom of page. You have to scroll a lot to see the second image. Now you will see that the second image will only be loaded once the user scrolled to the second one. So this will decrease the page load time and hence improves the performance of your website.
First create 2 image tags and give class attribute to access it in Javascript and data-src attribute. It is a custom attribute which we can use to get the actual path of image. DO NOT use src attribute as it will actually load the image, which we do not want. Give both images width as 100% so they will be completely visible inside the browser window.
<!-- Displaying first image -->
<img data-src="image-1.jpg" class="image" alt="1"><br>
<!-- Displaying second image but at bottom -->
<img data-src="image-2.jpg" class="image" alt="2" style="margin-top: 1000px;">
<!-- Image should not overflow the window -->
<style>
.image {
width: 100%;
}
</style>
Load image when scrolled
Then we create a built-in intersection observer which will be called automatically when page is scrolled and will return the items which are visible. We can check if each item is intersection (inside the browser window). We will get the data-src attribute and place it as src attribute, so in this way it will be loaded asynchronously. Once an image is loaded we do not want it to be loaded again, so we will disable it from observing again by calling the unobserve(item) method.
<script>
// IntersectionObserver is a built-in javascript object
var observer = new IntersectionObserver(function (items, self) {
// Loop through all visible items
for (var a = 0; a < items.length; a++) {
// Check if item is in visible area of browser
if (items[a].isIntersecting) {
// Debug the img tag
console.log(items[a].target);
// Get image data-src (custom) attribute
var src = items[a].target.getAttribute("data-src");
// Load the image
items[a].target.setAttribute("src", src);
// Should not call this function for same image again
self.unobserve(items[a].target);
}
}
});
</script>
At this point if you run the script, nothing happens. Because we havn’t tell it which items needs to be observed. Since we have given a class attribute to images so we can get all images having that class. Loop through each image and set it to be observed by observer using it’s instance.
<script>
// Get all images
var image = document.getElementsByClassName("image");
// Loop through each image
for (var a = 0; a < image.length; a++) {
// Make it observable
observer.observe(image[a]);
}
</script>
Conclusion
There are also many libraries available which can do the lazy loading for you. But nothing gives more control than writing your own code. So using this Vanilla JS way you can use intersection observers to lazy load images you want as per required.
Sprite is a computer graphics term for a two-dimensional bitmap that is integrated into a larger scene, most often in a 2D video game. Which means that small images are combined into one large image to reduce the number of requests on your server. Sprites helps a lot to reduce the number of HTTP requests.
In CSS sprites, we combine multiple images into a single image. So, if you are using 12 small images in your CSS, it will take 12 requests without sprite. Now if you combine all these images into one image, you will need only 1 request.
The basic principle is, you will combine multiple images into one large image. When you try to access it, the web server will not fetch the new copy of each image everytime you request it. Instead it will fetch just one image which contains all images and you can display them by specifying their position. Same as the image above.
So we will first combine all necessary images into one image and save it as a “sprite.png”. Then we will display the image by telling it’s position. We will be using two files, 1st for combining multiple images into one (save-sprite.php) and 2nd to display the images from sprite.
Generate sprites
First we create an HTML5 canvas tag where all images will be drawn. Give it unique ID to be accessible in Javascript and give it appropriate width and height.
Then we create an array of images which holds width, height and path (src) of each image. We will be looping through this array to automatically draw image on canvas. Also a counter variable to tell the number of current image under process.
Then we get the canvas object and 2D context of canvas. Create a variable named marginLeft to automatically draw the image after the previous one. If this is not specified, then all images will be placed on top of other.
After that, you will create a recursive function that will draw all images inside the array. Inside this function, create a new Image() object and set the image path in src attribute. Call onload function with this image object to wait for the image to fully loaded. The draw the image using drawImage(imageObj, x, y, width, height) function that will render the image on canvas.
Increase margin from left for next image, increment the counter. If there is more images in array then recursion occurs by calling the function itself inside the function. Otherwise if all images are rendered then we will convert that canvas into image and call an AJAX function to save this image data as a sprite.
<!-- Canvas where all images will be drawn -->
<canvas id="myCanvas" width="1000" height="500"></canvas>
<script>
// An array where all images should be entered
var images = [{
width: 308,
height: 183,
src: "image1.png"
}, {
width: 206,
height: 260,
src: "image2.png"
}];
// A variable used to get the number of current image
var count = 0;
// Get canvas element
var c = document.getElementById("myCanvas");
// Get canvas context used for drawing
var ctx = c.getContext("2d");
// Give margin to each image so they will be aligned horizontally
var marginLeft = 0;
// A recursive function which will keep calling itself
// until all images are drawn on canvas
function loadImage() {
// Create new image object
var imageObj = new Image();
// Set the path of image
imageObj.src = images[count].src;
// Wait till image fully loaded
imageObj.onload = function() {
// Draw image on canvas given image object, x, y, width & height
ctx.drawImage(imageObj, marginLeft, 0, images[count].width, images[count].height);
// Increase margin from left
marginLeft += images[count].width;
// Increment to next image
count++;
// If there is more image to draw
if (count < images.length) {
// Recursive occur here
loadImage();
} else {
// All images has been drawn on canvas
console.log("All images loaded");
// Convert the canvas into PNG image
var image = c.toDataURL("image/png", 1);
// Create AJAX request object
var ajax = new XMLHttpRequest();
// Set method to POST, file name and asynchnronous
ajax.open("POST", "save-sprite.php", true);
// Set headers in POST request
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Send the request and pass image data
ajax.send("image=" + image);
// Listen for server request changes
ajax.onreadystatechange = function () {
// Request is successful if ready state is 4 and status is 200
if (this.readyState == 4 && this.status == 200) {
// Print response sent from server
console.log(this.responseText);
}
};
}
}
}
loadImage();
</script>
Save sprite image
Create a new file named “save-sprite.php” and paste the following code in it. This will give the image data from client and remove the “base64” part from it as that is not necessary. When using AJAX post request we should also convert all spaces into plus sign and then decode the base64 string. Finally you can save the image as separate file.
To display an image we will create a <div> tag and set the background image as sprite. Given the background position allow you to display specific portion of sprite image. For example, if your sprite has 3 images of 100px width each, then your total sprite will be of 300px in width. To display the second image you have give the background position as -100px so it will move the image from left to right.
Sprites are very useful specially in video games where optimization and performance is very important. So instead of loading all car’s types (Lamborghini, Bugatti, Ferrari, Mclaren) as 4 images they create a single sprite named “cars-sprite.png” which holds all the images of cars. This is just an example, you can categories the sprites as much as required. The point is to send minimum requests on the server.
Hope that helps you in your upcoming or legacy projects to reduce the number of HTTP requests using sprites. If you face any problem, feel free to ask in the comment’s section below.
Search is one of the feature which is needed in almost every website. Whether you are working on admin panel or user side, you need to provide a functionality where user can search and get data. So, in this article, we will discuss how you can search a string in all tables and columns of a database. We will be using PHP and MySQL.
When it comes to admin panel, then it require to search all tables and all its fields in database for search query. For example, admin wants to know all payments transferred via account number 1234. Then he will simply type 1234 and it automatically scan all tables (including the payment’s table) and display the data.
While in typical environment, you have to manually set the table name along with column name to search. So we will make it to search complete database for searched query.
Create a form
Create a simple form where user can enter string and we will search that string in whole database.
Create a new file named “search.php” and paste the following code in it:
<?php
// Check if form submits
if (isset($_GET["submit"]))
{
// Get searched query
$search = $_GET["search"];
// Connect with database
$conn = mysqli_connect("localhost", "root", "", "classicmodels");
}
?>
First we need to get all tables inside the database. We will be running the MySQL command SHOW TABLES and it will return all tables. Then we will loop through each table. Here we will get object like “Tables_in_dbname” where “dbname” will be your database name. In this case, it will be “Tables_in_classicmodels”.
It will give us the table name which can be used to get all columns (structure) and data inside the table.
$tables = mysqli_query($conn, "SHOW TABLES");
while ($table = mysqli_fetch_object($tables))
{
$table_name = $table->{"Tables_in_classicmodels"};
// put below code here
}
Now we need to get all the rows and columns of this table. Since we do not know the number of each table so we will create an array that will store all columns of each table with LIKE clause on each column.
<caption>
We can display column name as caption of each table using <caption> tag. Then we will run the query to get all columns of each table and loop through each column and display that as TH (table heading). After that, we will need the $columns array again when display row data. So we will use the function mysqli_data_seek($columns, 0) and it will move the database cursor of this object to zero.
We also will push the column name in an array with LIKE clause so it will become “WHERE column1 LIKE ‘%value%’ OR column2 LIKE ‘%value%’ “ and so on. We can combine this array into string using implode function and append in $sql variable.
Finally we will run this query and loop through each row returned from it. Inside the row array we also need to run the column array to get all columns of that table. Make sure to call mysqli_data_seek function otherwise you won’t be able to see more than 1 row.
<?php
// put this code inside above while loop
// Create SQL query to get all rows (more on this later)
$sql = "SELECT * FROM " . $table_name . " WHERE ";
// An array to store all columns LIKE clause
$fields = array();
// Query to get all columns from table
$columns = mysqli_query($conn, "SHOW COLUMNS FROM " . $table_name);
?>
<table>
<!-- Display table name as caption -->
<caption>
<?php echo $table_name; ?>
</caption>
<!-- Display all columns in table header -->
<tr>
<?php
// Loop through all columns
while ($col = mysqli_fetch_object($columns)):
// Use LIKE clause to search input in each column
array_push($fields, $col->Field . " LIKE '%" . $search . "%'");
?>
<!-- Display column in TH tag -->
<th><?php echo $col->Field; ?></th>
<?php
endwhile;
// Move cursor of $columns to 0 so it can be used again
mysqli_data_seek($columns, 0);
?>
</tr>
<?php
// Combine $fields array by OR clause into one string
$sql .= implode(" OR ", $fields);
$result = mysqli_query($conn, $sql);
// Loop through all rows returned from above query
while ($row = mysqli_fetch_object($result)):
?>
<tr>
<?php
// Loop through all columns of this table
while ($col = mysqli_fetch_object($columns)):
?>
<td>
<?php
// Display row value from column field
echo $row->{$col->Field};
?>
</td>
<?php endwhile; mysqli_data_seek($columns, 0); /* end of column while loop */ ?>
</tr>
<?php endwhile; /* end of row while loop */ ?>
</table>
So that’s it. Hope that helps you in your almost every project because in every website you will need to allow user to search some string in whole database. If you face any problem, please feel free to ask in the comment’s section below.
Learn how you can recursively search string in all folders in your cPanel’s file manager.
Suppose you are working on cPanel on a very big project, now you want to search some string in all folders and in all of their files in cPanel. There are very few cPanel that provide such functionality to search some specific string in all files in your domain. This script will allow you to do this.
You just needs to put this file in the root folder of your domain where you want to perform search. For the sake of simplicity we are creating a simple form where you will enter the string that needs to be searched and hit enter to do the search.
Create a recursive function that will search for all files. While calling this function you need to send the root folder path in the first call. If you are using Laravel you need to use Laravel built-in base_path() instead of core PHP dirname(__FILE__). Create a new file named “search.php” and paste the following code in it:
search.php
<?php
// A recursive function to search all files
function get_directory_content($directory)
{
//
}
// Check if form submits
if (isset($_GET["submit"]))
{
// Get searched query
$search = $_GET["search"];
// Where all files (where that string is found) will be stored
$results = array();
// Send root folder path to start the search
get_directory_content(dirname(__FILE__));
}
As we will be using $search and $results variable inside the function so we need to declare them as global variables, otherwise they will not be accessible inside the function. Also we need to get all the files inside the folder which is being passed as parameter, loop through all the files.
Skip “.” and “..”
In Unix file system there are 2 commands inside every folder which are “.” and “..”. The first one means the current directory and second one means the parent directory. In this case we will skip the loop by using continue; command.
global $search, $results;
$files = scandir($directory);
foreach ($files as $file)
{
if ($file == "." || $file == "..")
{
continue;
}
}
Next, we will check if the incoming name is a directory or a file. If it is a file then we will simply process it for searching text. If it is a directory then we will call the recursive function again to get its files too. In this way it will check for all files no matter how many nested folders you have.
Then we will get the content of that file and check if that searched query exists in that file. stripos(content, search) will search case-insensitively which means that you do not have to worry about small and capital letters.
stdClass in PHP
If that text is found in file then we will create a custom object using built-in PHP stdClass() class. If you are working on Laravel then you need to push back-slash before the class name, for example for Laravel \stdClass() because Laravel classes works in namespaces.
Set the name of file in that object and lastly push that object in the $results array we created in second step.
if ($is_file)
{
$content = file_get_contents($path);
if (stripos($content, $search) !== false)
{
$obj = new stdClass();
$obj->file_name = $file;
array_push($results, $obj);
}
}
Now we will know the name of file where your searched string is found. But we would also want to know the line number in case you have larger files. Also if you were searching for some variable then it will have multiple occurrences in same file so we need to create an array. Another variable will be created to tell the line number of each occurrence.
In order to check each line number we need to loop through each line of that file. To do that, first open the file in read mode using fopen(“file_name”, “r”) and this will return the file handler which we can use later.
fgets in PHP
fgets(file_handler, length) function will read one line each time it is called and by specifying length paramter it will move to the next line every time it is called. In each iteration, we are increasing the number of line by incrementing the variable with 1.
Then we will use the same function to search but this time for single line and not for whole file. If found then we will push that line number in $lines array.
After the while loop we will assign that lines array to our custom object we created in previous step. So lines array will also be sent along with file name which we did in previous step.
Hope this tutorial helps you in search your query string in all folders in your cPanel. If it did not work, or if you are having any error in this, kindly do let us know.
We will teach you how you can convert your <div> into an image using html2canvas library.
Download html2canvas library
First, you need to download the library called Html2Canvas and paste in your project folder. You can download it from here. After that, paste the JS file in your project and include it via script tag.
<script src="html2canvas.js"></script>
Then give a unique ID to the div tag whose screenshot you wants to take. After that, create a function in Javascript which will be called when you want to take the screenshot. We will be calling that function on some button press, but you can use it as per your needs.
<script>
// A function to convert the required div to image
function doCapture() {
//
}
</script>
<button onclick="doCapture();">Capture</button>
Scroll to top
In order to make this library works, your scroll position should be on header of your site. Even if you want to take the screenshot of footer or any other section in the middle. Your header must be visible before converting the div to image. So we will move the scroll to top by simply calling the window.scrollTo(x, y) function. And pass the x, y coordinates as 0 both.
function doCapture() {
// Move the scroll on top of page
window.scrollTo(0, 0);
}
Calling html2canvas function
Now we need to call the html2canvas function, it’s first parameter will be the tag which needs to be converted as image. As we already would have given it some unique ID attribute, so we can get it easily by calling document.getElementById(id) function. Lastly the library provides a function called then() which sends a callback when the div has been converted to image successfully. Basically it sends a canvas object and we can get the image data from that canvas. We can call the toDataURL(imageType, quality) function to get the image type. Possible image types are “image/jpeg” or “image/png” and the value of quality parameter ranges from 0 to 1. By setting the value to 0.9 we can get the minimum compression and maximum quality on image.
function doCapture() {
window.scrollTo(0, 0);
// Convert the div to image (canvas)
html2canvas(document.getElementById("capture")).then(function (canvas) {
// Get the image data as JPEG and 0.9 quality (0.0 - 1.0)
console.log(canvas.toDataURL("image/jpeg", 0.9));
});
}
Call AJAX with base64 image
In order to save this image in our server, you need to call an AJAX request and pass this image data as parameter.
function doCapture() {
window.scrollTo(0, 0);
html2canvas(document.getElementById("capture")).then(function (canvas) {
// Create an AJAX object
var ajax = new XMLHttpRequest();
// Setting method, server file name, and asynchronous
ajax.open("POST", "save-capture.php", true);
// Setting headers for POST method
ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Sending image data to server
ajax.send("image=" + canvas.toDataURL("image/jpeg", 0.9));
// Receiving response from server
// This function will be called multiple times
ajax.onreadystatechange = function () {
// Check when the requested is completed
if (this.readyState == 4 && this.status == 200) {
// Displaying response from server
console.log(this.responseText);
}
};
});
}
Save file on server
Now create a server file named save-capture.php and paste the following code to save the incoming data as image.
<?php
// Get the incoming image data
$image = $_POST["image"];
// Remove image/jpeg from left side of image data
// and get the remaining part
$image = explode(";", $image)[1];
// Remove base64 from left side of image data
// and get the remaining part
$image = explode(",", $image)[1];
// Replace all spaces with plus sign (helpful for larger images)
$image = str_replace(" ", "+", $image);
// Convert back from base64
$image = base64_decode($image);
// Save the image as filename.jpeg
file_put_contents("filename.jpeg", $image);
// Sending response back to client
echo "Done";
You can also resize the saved image without stretching.
We will be using PHPSpreadsheet library which provides all the functionality to create and read the Excel sheets in PHP. You can download it via composer, make sure you have downloaded and install the composer in your system. You can download the composer from here. Right now there is no standalone version of this library that is why you must have composer installed in your system. Open command prompt in your project folder, if you are working directly on cPanel then you might need to open terminal from cPanel home page like the screenshot below:
While in your project folder in command prompt run the following command to install the library. If you are using Mac or Linux make sure you have folder permissions enabled because this library will create a lot of files and folders.
composer require phpoffice/phpspreadsheet
Create excel file
Open your file from where you want to run the function to create Excel file and paste the following code in it. We will be using file named index.php:
<?php
// Including all files from library
require "vendor/autoload.php";
// Creating a new sheet in Excel file
$spreadsheet = new PhpOffice\PhpSpreadsheet\Spreadsheet();
// Create a write object to save the file and pass spreadsheet instance as parameter
$writer = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
// Save the file named "Test.xlsx"
$writer->save("Test.xlsx");
?>
Create Table Row
We will be creating a simple table that will display the data from database. As Excel sheets use row and column address to save the values, also known as Cells. So paste the following code that will create 5 columns in first row of first sheet:
// Get first sheet from file and set value in specified columns respectively
$spreadsheet->getSheet(0)->setCellValue("A1", "Customer Name");
$spreadsheet->getSheet(0)->setCellValue("B1", "Phone");
$spreadsheet->getSheet(0)->setCellValue("C1", "Address Line");
$spreadsheet->getSheet(0)->setCellValue("D1", "Check number");
$spreadsheet->getSheet(0)->setCellValue("E1", "Amount");
Adjust the width of cells
If you run the code now you will see a new Excel file will be created in your project root folder. But all cells will have equal width which makes it difficult to see full content of cell. We need to find a way to make it dynamic so that it will automatically adjust the cell size according to its content. We will be using setAutoSize(bool) function for this purpose as following:
Now we need to highlight the cells of header so they will be prominent than the others. We will be creating an array that will hold all the styles. For simplicity, we will be setting the background color (fill color) as red and font color as white.
$styles = [
"fill" => [
"fillType" => PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
"startColor" => [ "rgb" => "FF0000" ]
],
"font" => [
"color" => [ "rgb" => "FFFFFF" ]
]
];
// Set the range of cells where this style should be applied
$spreadsheet->getSheet(0)
->getStyle("A1:E1")
->applyFromArray($styles);
Add data in cells from database
We will be using a sample database named classicmodels of course you will be using your own. We will connect with database and run the required query. Then we will loop through all the records returned from that query and create 5 cells in each iteration and after that move to the next row.
// Connecting with database
$conn = mysqli_connect("localhost", "root", "", "classicmodels");
// Executing the required query
$result = mysqli_query($conn, "SELECT * FROM payments INNER JOIN customers ON customers.customerNumber = payments.customerNumber");
// Start from second row
$count = 2;
while ($row = mysqli_fetch_object($result))
{
// Add required data
$spreadsheet
->getSheet(0)
->setCellValue("A" . $count, $row->customerName);
$spreadsheet
->getSheet(0)
->setCellValue("B" . $count, $row->phone);
$spreadsheet
->getSheet(0)
->setCellValue("C" . $count, $row->addressLine1);
$spreadsheet
->getSheet(0)
->setCellValue("D" . $count, $row->checkNumber);
$spreadsheet
->getSheet(0)
->setCellValue("E" . $count, $row->amount);
// Move to next row
$count++;
}
Reading data from cells
You can read the data from any Excel file using IOFactory class and loop through rowIterator. Each row will return all cells in it and you can loop through all cells using cellIterator. To get the cell value you can either call getValue() or getCalculatedValue(). If you are using some formula in your cells then you need to use getCalculatedValue() and it will return the calculated value after performing that function. But you can also use this for normal cells too.
<?php
// Get Excel file
$reader = PhpOffice\PhpSpreadsheet\IOFactory::load("Test.xlsx");
// Get all rows in first sheet
$rows = $reader->getSheet(0)->getRowIterator();
?>
<table>
<?php
// Loop through all rows
// $count will be use to make first table row as heading
$count = 1; foreach ($rows as $row) {
?>
<tr>
<?php
// Get all cells in each row
$columns = $row->getCellIterator();
?>
<?php
// Loop through all cells
foreach ($columns as $column) {
?>
<?php if ($count == 1) { ?>
<th>
<?php echo $column->getCalculatedValue(); ?>
</th>
<?php } else { ?>
<td>
<?php echo $column->getCalculatedValue(); ?>
</td>
<?php } ?>
<?php } ?>
</tr>
<?php $count++; } ?>
</table>
Downloading the excel file
In some cases you want to give users the ability to download the Excel file in his computer. After HTML5 it became so easy that you just have to create an anchor tag, set the path of file that needs to be downloaded and give the attribute download.
So that’s it. Hope you find it super simple to create and read Excel files using PHP and it might help if you ever came across with some project that involve the use of spreadsheets. If you face any problems or have any suggestions, please feel free to tell in the comments section below.
Download with progress bar
However, there is another approach to download the file. You can display a progress bar to know how much of the file has been downloaded. Learn more from here.
If you link a PDF file saved in your server with an anchor tag and give it a “download” attribute. It will make the file downloadable. When user clicks on it, it will be downloaded on his computer. But in some cases, you want to view the PDF file in the browser. Rather than downloading it in client’s system.
FPDF
We are going to use the library named FPDF you can download it from it’s official site. You will get ZIP file in your download, extract it and you will get just 1 folder. You need to copy that folder in your project root folder where it can be accessible. In that folder you will also find a folder named “font” that will be used if you want to add more fonts in your PDF file. By default it came up with 14 fonts at the time of writing this.
Create invoice PDF
So we are going to create a simple invoice page which is a common example in E-commerce sites. There, once you buy any product then an invoice has been generated which contains all the order details. It typically contains company logo, buyer name & address, all products which were added in cart and their quantity & price. Lastly, it has total sum of all products. Some also have shipping cost so they display grand total which is the sum of all products price and the shipping cost.
In order to create PDF view in your browser you first needs to include the fpdf.php inside your downloaded folder. Then you need to create an instance of FPDF class, we will be using this object throughout this tutorial. Then needs to add a page in PDF. Otherwise it will throw an exception that no page has been found in PDF. Lastly you will render the PDF in browser by calling the output() function with your PDF instance. We will be using index.php to display the PDF file. But you might be creating a separate file for viewing PDF. Paste the following code in your index.php file:
<?php
// Include the PDF class
require_once "fpdf181/fpdf.php";
// Create instance of PDF class
$pdf = new FPDF();
// Add 1 page in your PDF
$pdf->AddPage();
// Render the PDF in your browser
$pdf->output();
?>
Create header
Header will contain an image which can be served as a logo on top left and on right. You can either display the name of company or the subject of report. Example of subject of report can be “report”, “invoice”, “letter” etc. In order to insert image in your PDF file you need to call the Image(src, x, y, width, height) function. Here, src will be the source of image which needs to be placed, typically we place company logo in PDF. X & Y are the co-ordinates where image will be placed and width & height are self-explanatory I believe. Paste the following code after AddPage() function and before the output() function:
<?php
// Place image on top left with 100px width
$pdf->Image("logo.jpg", 10, 10, 100);
// Set Arial Bold font with size 22px
$pdf->SetFont("Arial", "B", 22);
// Give margin from left
$pdf->SetX(160);
// Write text "Invoice" with 0 width & height (it will still be visible)
$pdf->Cell(0, 0, "Invoice");
// Move the cursor to next line
$pdf->Ln();
?>
Output – PDF view in browser
Display database data in PDF
Suppose some customer have purchased something from your website and you have saved his selected products in your database. Now, you need to show these values from database inside the PDF. We are going to show the database data in table format. We will be using Cell() function with PDF instance and it’s parameters are: Cell(x, y, text, border, ln, alignment, fill). It’s explanation is given below. First we are going to create a header for table which will be highlighted from other rows of the table:
X
Margin from left
Y
Margin from top
text
Text which needs to be displayed
border
Border around the text (1 means 1px)
ln
Where should next cell starts (0 means to right, 1 means next line)
Alignment
Alignment of text (can be “L” for left, “R” for right, “C” for center and “J” for justify)
Fill
Whether this cell nexts to be filled or not (true / false)
Now we will run the query on database and display all returned records in table rows. But first we need to make the font from bold to normal because bold only looks good for headings.
<?php
// Setting the font to Arial normal with size 16px
$pdf->SetFont("Arial", "", 16);
// Connecting with database
$conn = mysqli_connect("localhost", "root", "", "classicmodels");
// Getting records from database
$result = mysqli_query($conn, "SELECT * FROM orderDetails WHERE orderNumber = '10101'");
// Iterate through each record
while ($row = mysqli_fetch_object($result))
{
// Create cells with 50px width, 10px height and 1px border
$pdf->Cell(50, 10, $row->productCode, 1);
$pdf->Cell(50, 10, $row->quantityOrdered, 1);
$pdf->Cell(50, 10, $row->priceEach, 1);
// Moving cursor to next row
$pdf->Ln();
}
?>
Output – PDF view in browser
In these type of cases you may also wanted to show the total of all products which includes the sum of all products unit price multiplied by quantity. Also you also want to add the shipping cost if the product needs to be delivered physically. So first we will add all the product’s price in a variable and then we will add the shipping cost in it. Then we will display 3 sections, 1 for product’s total price, 1 for shipping cost and 1 for grand total which will be sum of total price and shipping cost. We are going to highlight the grand total section too because it is the final price and it needs to get attention:
At this point, if you access the “Invoice.pdf” from the address bar. You will be able to view the PDF file in your browser. Now we need to make it downloadable.
Downloading the PDF
To download the PDF as external file or exporting the file in your computer, you need to do few steps. First you need to change your output() function and make it to accept two arguments, first will be the name of file that will be save in your server and second will be the character F which indicates that user wants to create a file and instead of displaying in browser. Then you need to pass some headers which will download the file, and finally you can remove the file from server if you want. Because in some cases you just want the file to get downloaded by user and not to keep in your server.
<?php
// Creates a file in server
$pdf->output("Invoice.pdf", "F");
// Tell that the file will be PDF
header("Content-type: application/pdf");
// Set the file as attachment and set its name to "Invoice.pdf"
header("Content-disposition: attachment; filename = Invoice.pdf");
// Read the source file (which needs to be downloaded)
readFile("Invoice.pdf");
// Delete the file from server
unlink("Invoice.pdf");
?>
That’s it. If you face any problem in following this tutorial, please feel free to ask in the comments section below.
There is a jQuery ratings plugin called “Starrr”. It allows you to get feedback input from the user by displaying him stars. Lower stars means they didn’t liked your product or service. And higher stars means they liked your product or services.
Let’s get started
First you need to download and integrate a small and lightweight Javascript library in your project. The name of library is Starrr and you can download it from here. You may get the downloaded file in ZIP format so unzip it (of course). In the unzipped folder, you will find a folder named “dist”. You will find 2 files, one is CSS and second will be of JS. You need to copy both these files and place them in your project folder. To setup the star ratings in your website, you need to include 3 CSS files and 2 JS files.
CSS
Bootstrap
Font Awesome
Starrr
JS
jQuery
Starrr
So paste the following code at the top of file where you want to show ratings. We have used the CDN for Bootstrap, Font Awesome and jQuery for direct integration. But you can download them in your project and give relative path if you want. If you are already working on some project, then most probably you already have those CSS & JS files. Because they are used mostly in design part.
You might already have a database with all the data and you just want to integrate this star ratings in it. So you might have an E-commerce site where you want to give ratings to products, or may have an online Job Portal where you want to give ratings to Clients or Freelancers etc. So for the sake of simplicity we are are creating simple products with just 2 fields, you might have a lot of other fields too but it will give you enough idea how to implement in your project. Create a new database in your phpMyAdmin named tutorials and run the following queries to create 1 table named products and other ratings where all ratings of each product will be stored:
--
-- Database: `tutorials`
--
-- --------------------------------------------------------
--
-- Table structure for table `products`
--
CREATE TABLE `products` (
`id` int(11) NOT NULL,
`name` text NOT NULL
);
--
-- Dumping data for table `products`
--
INSERT INTO `products` (`id`, `name`) VALUES
(1, 'Macintosh'),
(2, 'iMac'),
(3, 'iPod'),
(4, 'Apple II');
-- --------------------------------------------------------
--
-- Table structure for table `ratings`
--
CREATE TABLE `ratings` (
`id` int(11) NOT NULL,
`product_id` int(11) NOT NULL,
`ratings` int(11) NOT NULL
);
Display all products
Now you need to display all products stored in your database. We are just displaying product name but surely you will be displaying other details too. Along with each product we will create a form to get product ID and show 5 stars from where user can give ratings and a submit button.
Run the project now and you will be able to see all products stored in your database along with 5 stars to give ratings. Now you need to save ratings in ratings table when user click on submit button.
Save ratings
Our form creates a hidden input field where it is storing product ID, so now we first need to get the ratings and save those ratings in that particular product. This jQuery ratings plugin will return the value as an integer. You need to change the starrr() function to attach an change event that will be fired when user change his ratings and we will save that in a variable. Then we will attach an submit event in form and call an AJAX request and send the product ID and rating of user.
Creates a new file named save-ratings.php that will store the ratings in database. You can also store user ID if you have login & registration system in your website, by getting the user ID from session or from cookies. So make the following changes in your above code and it will be able to save ratings in database:
index.php
var ratings = 0;
$(function () {
$(".starrr").starrr().on("starrr:change", function (event, value) {
ratings = value;
});
});
function saveRatings(form) {
var product_id = form.product_id.value;
$.ajax({
url: "save-ratings.php",
method: "POST",
data: {
"product_id": product_id,
"ratings": ratings
},
success: function (response) {
// whatever server echo, that will be displayed here in alert
alert(response);
}
});
return false;
}
save-ratings.php
<?php
$product_id = $_POST["product_id"];
$ratings = $_POST["ratings"];
$conn = mysqli_connect("localhost", "root", "", "tutorials");
mysqli_query($conn, "INSERT INTO ratings (product_id, ratings) VALUES ('$product_id', '$ratings')");
// whatever you echo here, will be displayed in alert on user side
echo "Saved";
Go ahead and give ratings to some products and check your ratings table in your database, you will see your ratings along with product ID. This is where you can store user ID too from session or cookies if you are using login or sign up features.
Display average rating
We are already creating a loop to display all products, this is where we will get all ratings of each product and calculate it’s average and display as stars. jQuery “starrr” ratings plugin also allows you to initialize the stars widget with an integer valule. So go ahead and paste the following code in your product’s while loop block:
while ($row = mysqli_fetch_object($result)) {
// Getting ratings of current product using ID
$result_ratings = mysqli_query($conn, "SELECT * FROM ratings WHERE product_id = '" . $row->id . "'");
// Adding total ratings from each user
$ratings = 0;
while ($row_ratings = mysqli_fetch_object($result_ratings))
{
$ratings += $row_ratings->ratings;
}
// Calculating average from all ratings
$average_ratings = 0;
$ratings_count = mysqli_num_rows($result_ratings);
if ($ratings_count > 0)
{
$average_ratings = $ratings / $ratings_count;
}
?>
<!-- This is where product stars will be displayed -->
<!-- data-rating attribute will be used in Javascript below -->
<div class="ratings" data-rating="<?php echo $average_ratings; ?>"></div>
<!-- Product name and other fields -->
<!-- Form goes here -->
<?php
}
?>
<script>
// Getting all div with ratings class
var rating = document.getElementsByClassName("ratings");
// Loop through all divs
for (var a = 0; a < rating.length; a++)
{
// Display star on each div based on data-rating attribute value
// readOnly will prevent the user changing it's value
$(rating[a]).starrr({
readOnly: true,
rating: rating[a].getAttribute("data-rating")
});
}
<script>
That’s it, you have successfully added a star rating widget in your website. Everyone will be using this according to his project requirements and everyone will have different scenarios based on his needs. So if you have any problem, feel free to ask in the comments section below.
Another jQuery ratings plugin
You can also get the feedback from your users by displaying them emojis. User can select an emoji to describe his experience with your product or service. You can learn how to integrate that in your website from here.
Google maps can be embedded in your website using PHP without providing API key. You just need to enter your address. Or you can enter coordinates, longiude and latitude.
Google Maps is a web mapping service developed by Google. It offers satellite imagery, aerial photography, street maps, 360° panoramic views of streets, real-time traffic conditions. Also, route planning for traveling by foot, car, bicycle and air, or public transportation.
By using the Google Maps API, it is possible to embed Google Maps into an external website, on to which site-specific data can be overlaid. Although initially only a JavaScript API, the Maps API was expanded to include an API for Adobe Flash applications. But this has been deprecated. Adobe Flash was a service for retrieving static map images, and web services for performing geocoding, generating driving directions, and obtaining elevation profiles. Over 1,000,000 web sites use the Google Maps API, making it the most heavily used web application development API. In September 2011, Google announced it would deprecate the Google Maps API for Flash.
As of 21 June 2018, Google increased the prices of the Maps API and requires a billing profile. But some people didn’t find themselve comfortable with providing their credit card information. Or they are just students who want to use Google Map services. So by following the below tutorial you will be able to show Google Map in your website without providing API key. You just need to enter either address or co-ordinates like latitude and longitude.
Google maps by address without API key
Create a simple form that will have an input field for entering address via input field. And a submit button which when clicked will submit the form.
Now we need to create a PHP block that will be executed when the form submits. In that block, we will get the address entered by user in a separate variable. Since address might have spaces so we will be converting those spaces into + sign. Lastly, we will create an iFrame tag to render the map. &output=embed is important since it tells the Google Map’s server that we are going to embed the map in an iFrame.
Google maps by latitude and longitude without API key
Create a simple form that will have 2 input fields for entering latitude and longitude via input field. And a submit button which when clicked will submit the form.
Now we need to create a PHP block that will be executed when the form submits. In that block, we will get the latitude and longitude co-ordinates entered by user in separate variables. Lastly, we will create an iFrame tag and pass those co-ordinates to render the map. Make sure to separate the values using comma (,).
It will return the latitude and longitude of the user that you can embed in iframe and it will render the map on the browser.
Note: Your browser will ask for permission to access your location. You need to allow it to return the co-ordinates.
Conclusion
Although it has some limitations, for example you cannot update the marker once the map is fully loaded. In order to change the location of marker, you can re-draw the map again. But it will give you enough functionality so that if you are receiving latitude and longitude of user’s location from some android/iOS application and you wanted to show that location on admin panel. You can easily do that by following this tutorial. That’s all for now, if you face any problem or need any help feel free to ask in the comments section below.
Following this tutorial, you will be able to do realtime chat in Firebase in your website. We will be using Javascript in this tutorial.
Firebase
Firebase provides the ability to use non-relational database which means data will be stored in objects and arrays. It uses JSON format to save data in database. The structure of data is similar to as stored in Mongo DB where each table is known as collection. Each row is resembled with documents inside collection.
By default, Firebase provides 15 GB of data where you can store text, images and documents too. One of the biggest advantage of using Firebase is that it has built-in support for realtime notifications. That means that when a new item is added or removed it will automatically be notified in respective events. So Firebase ease the process of setting up Socket, Node JS and Mongo DB.
Firebase console
Goto Firebase Console and create a new project. Set the name of project and click “Continue”, you can disable the analytics for now. After that, click on “web” icon to integrate Javascript API in your project. Set the name of your project again and DO NOT set Firebase hosting. Because you will be running on your own localhost or hosting server. Then you will be displayed a code which you can copy and paste at the top of your project.
In your firebase console, goto “Database” tab from left menu and click on “Realtime Database”. For now, you can setup the database in test mode. The code you copied from Firebase console will only have firebase-app.js. But you will also need firebase-database.js in order to use database. We will be using file named “index.php” where all chat operations are performed. Below code has some empty values but when you copy from Firebase console then they will be filled automatically as per your project.
index.php
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/6.6.1/firebase-app.js"></script>
<!-- include firebase database -->
<script src="https://www.gstatic.com/firebasejs/6.6.1/firebase-database.js"></script>
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
</script>
Sending chat message in Firebase
Open your browser console by right click on empty area of page and select “Inspect Element” from context menu and open the “Console” tab. Make sure your internet is connected and check if there is any error. When it comes to sending message, for the sake of simplicity we will be saving username and message in the database. First we need to get the name of user when page opens. We can use Javascript built-in prompt() function to do that. Then we need to create a simple form with an input field to send message. When that form submits then we will call a function that will save the data in Firebase database.
The autocomplete field will make sure not to display old entered values in this field. At the end of sendMessage() make sure to return false. Otherwise the form will submits to itself and the page refreshed. firebase.database() will return an instance of Firebase database. You can either store it in a separate variable to re-use it or you can call it every-time you need to perform some action in database. When the data is saved then Firebase will fire an event that will be called when a new child is added. We will discuss that in details in next step.
The code below will create a new node named “messages”. It will give it a unique ID and save username and message in it. The nodes in database are called as “Childs” in Firebase database.
<script>
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
var myName = prompt("Enter your name");
</script>
<!-- create a form to send message -->
<form onsubmit="return sendMessage();">
<input id="message" placeholder="Enter message" autocomplete="off">
<input type="submit">
</form>
<script>
function sendMessage() {
// get message
var message = document.getElementById("message").value;
// save in database
firebase.database().ref("messages").push().set({
"sender": myName,
"message": message
});
// prevent form from submitting
return false;
}
</script>
Display messages from chat in Firebase
To display database data from Firebase we need to attach a listener called “child_added”. The main benefit of using this listener is that it simplifies the process of fetching the old messages from database. It is also used to listen to new incoming messages. So this event will be called in 2 situations.
When the page loads it will get all messages saved in database.
And second, when a new child is added in Firebase database.
Code below will create a list where all messages needs to be displayed and attach a listener which will be called automatically when the page loads. On each iteration it will return a snapshot object which is a Firebase database object and it contains child’s key and value.
On each iteration we are creating a new list and appending at the end of UL tag. As the child’s key is unique throughout the database, so we will be adding this as an ID to list item. This will be used when we try to delete message, it will be covered in detail in next step. We will be displaying delete button only if the message is sent from current user which means you can delete only those messages which are sent by you.
Button tag will have an attribute data-id which will be used to get the unique ID of message and an onclick event is attached which will be called when that button is pressed. At the end we are displaying sender’s name and message content.
<!-- create a list -->
<ul id="messages"></ul>
<script>
// listen for incoming messages
firebase.database().ref("messages").on("child_added", function (snapshot) {
var html = "";
// give each message a unique ID
html += "<li id='message-" + snapshot.key + "'>";
// show delete button if message is sent by me
if (snapshot.val().sender == myName) {
html += "<button data-id='" + snapshot.key + "' onclick='deleteMessage(this);'>";
html += "Delete";
html += "</button>";
}
html += snapshot.val().sender + ": " + snapshot.val().message;
html += "</li>";
document.getElementById("messages").innerHTML += html;
});
</script>
Delete messages from chat in Firebase
Since we have already created a button to delete message, now we need to create a function that will be called when that button is pressed. We are going to delete the message from database and notify all other users that, that message has been removed. You can either remove that message node from list item or you can simply change the text of message to “This message has been removed” like WhatsApp does.
Next time you refresh the page, that message will be removed altogether. First we are getting the unique ID of message from the data-id attribute of button. Then we call the remove() function of Firebase instance and it will remove that message child from database. As soon as the child is removed, Firebase has an event named “child_removed” which will be called with deleted child key and value. So we are attaching that listener which will return the deleted child key and value which can be used to remove or alter that node from list item.
Now a delete button will be displayed along with your sent messages, when clicked it will be removed from Firebase database and a message will be displayed saying “This message has been removed”.
function deleteMessage(self) {
// get message ID
var messageId = self.getAttribute("data-id");
// delete message
firebase.database().ref("messages").child(messageId).remove();
}
// attach listener for delete message
firebase.database().ref("messages").on("child_removed", function (snapshot) {
// remove message node
document.getElementById("message-" + snapshot.key).innerHTML = "This message has been removed";
});
That’s how you can do real-time chat in Firebase using Javascript. If you do not want to use Firebase and do chat with your own server. You need to follow this tutorial.