Create ZIP file with password – PHP

To create a ZIP file with password in PHP, there isn’t any need for third-party library. PHP provides a large variety of built-in functions to create a ZIP file. Also PHP has an in-built option for setting the password on ZIP files.

We will creating a simple script to allow user to upload multiple files, then will compress those files in ZIP and asking the password from user. And apply that password on that ZIP file.

We will be creating just 2 files, 1 for client (index.php) and 1 for server (upload.php). So, start off by creating a simple HTML form in file index.php:

Create form to select multiple files (index.php)

<form method="POST" enctype="multipart/form-data" action="upload.php">
</form>

enctype=”multipart/form-data” and method=”POST” are important in <form> tag to upload file.

<input type="file" name="files[]" required multiple />
<input type="submit" name="upload" />

multiple attribute will be used to allow user to select multiple files.

Upload, compress files to ZIP (upload.php)

<?php
    $zip = new ZipArchive();
?>

Creates a built-in ZipArchive class object and save it in variabled called $zip.

Call open() function from $zip object to create a new empty ZIP file in memory.

$zip->open("file.zip", ZIPARCHIVE::CREATE);
  • First parameter is the name of ZIP file you want to set.
  • Second is the action you want to perform, you can use OPEN, CREATE methods to read or write the file respectively.

As we are allowing user to select multiple files, we need to create a loop on user selected files:

for ($a = 0; $a < count($_FILES["files"]["name"]); $a++)
{
    //
}

Inside this loop, we have to get the content of each file separately:

$content = file_get_contents($_FILES["files"]["tmp_name"][$a]);

Then you have to call the addFromString() method on $zip object. It accepts 2 parameters, 1st is the name of file inside the ZIP archive, 2nd is the content of file. In this case, 2nd parameter is stored in variable called $content.

$zip->addFromString($_FILES["files"]["name"][$a], $content);

After the loop, we have to call the close() to free-up the space in memory.

$zip->close();

At this point, your index.php file will look like this:

<form method="POST" enctype="multipart/form-data" action="upload.php">
    <input type="file" name="files[]" required multiple />
    <input type="submit" name="upload" />
</form>

And your upload.php file will look like this:

<?php
    $zip = new ZipArchive();
    $zip->open("file.zip", ZIPARCHIVE::CREATE);
    for ($a = 0; $a < count($_FILES["files"]["name"]); $a++)
    {
        $content = file_get_contents($_FILES["files"]["tmp_name"][$a]);
        $zip->addFromString($_FILES["files"]["name"][$a], $content);
    }
    $zip->close();
?>

Applying password to archive (upload.php)

Create simple password input field in index.php file:

<input type="password" name="password" required />

And in upload.php file, after the open() method, call the setPassword() method and send user selected password as parameter:

$zip->setPassword($_POST["password"]);

And in loop, after addFromString() method, call setEncryptionName() method to apply password on each file in the ZIP:

$zip->setEncryptionName($_FILES["files"]["name"][$a], ZipArchive::EM_AES_256);
  • 1st parameter is the name of file.
  • 2nd parameter is the type of encryption algorithm used.

Below is the complete source code of both files:

index.php

<form method="POST" enctype="multipart/form-data" action="upload.php">
    <input type="file" name="files[]" required multiple />
    <input type="password" name="password" required />
    <input type="submit" name="upload" />
</form>

upload.php

<?php
    $zip = new ZipArchive();
    $zip->open("file.zip", ZIPARCHIVE::CREATE);
    $zip->setPassword($_POST["password"]);

    for ($a = 0; $a < count($_FILES["files"]["name"]); $a++)
    {
        $content = file_get_contents($_FILES["files"]["tmp_name"][$a]);
        $zip->addFromString($_FILES["files"]["name"][$a], $content);
        $zip->setEncryptionName($_FILES["files"]["name"][$a], ZipArchive::EM_AES_256);
    }
    $zip->close();
?>

Run the index.php file, upload some files and set the password. Your selected files will be archived to 1 and password will be applied.

If you want to ZIP your files and protect them with password in command line, follow here.

Right now, this only works for Mac OS X.

[wpdm_package id=’107′]

AJAX file upload with progress bar – Javascript, PHP

In this tutorial, we are going to show you how you can upload file with AJAX. We will also be displaying a progress bar. We will be using PHP.

AJAX file upload with progress bar

There are 2 types of progress bars, one with infinite progress loop similar to this:

and one which shows the number of percentage completed like this:

We will be using the 2nd progress bar as it is more accurate than the first one.

Select file

We will be using an AJAX function to upload user selected file on the server and show the progress bar of how much the file has been uploaded. We will be creating just 2 files, 1 for client (index.php) and 1 for server (upload.php). So, start off by creating a simple HTML form in file index.php:

<form method="POST" enctype="multipart/form-data" onsubmit="return onSubmit();">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" />
</form>
  • enctype=”multipart/form-data” and method=”POST” are important in <form> tag to upload file.

Prevent form from submitting

In order to upload file via AJAX, first we need to stop the default form action method. We can do this by return false from onsubmit attribute of <form> tag. All the code written in this tutorial is pure Javascript, there is no dependency of jQuery in this tutorial.

<script>
    function onSubmit() {
        return false;
    }
</script>

Get input type file in Javascript

Now, you have to get the user selected file and save it in a variable called file. document.getElementById(“file”) helps in getting the input type file object and it has an array of user selected files in a variable called files.

function onSubmit() {
    var file = document.getElementById("file").files[0];
    return false;
}

Call AJAX to upload file

To call an AJAX to upload the file, first create an built-in XMLHttpRequest object and save in variable ajax. This object is supported in all browsers and it is native Javascript object, no jQuery is required.

var ajax = new XMLHttpRequest();

Now call open(method, url, async) function from ajax object.

  • First parameter is the method of request GET or POST.
  • Second is the name of PHP file which will upload the file. In this case upload.php which will be created in next step.
  • Third is a boolean, whether the request is asynchronous or not. true for asynchronous. Asynchronous requests does not hang up the browser. Syncronized requests may block the browser if the script at upload.php is very time-taking.
ajax.open("POST", "upload.php", true);

Sending file via AJAX required an FormData object to be appended in the AJAX request. We can create a FormData object simply by the following line:

var formData = new FormData();
formData.append("file", file);
  • formData.append 1st parameter is the string which will used in upload.php file to upload the file and 2nd parameter is the user selected file. In this case, it is stored in variable file

Call the send() function from ajax object to actually call an AJAX request. It accepts 1 parameter that is of FormData object.

ajax.send(formData);

When response is received from server

ajax object has multiple functions that are called once the status of request is changed. For example, when server receives the request, if server does not exists, if server failed to respond etc. All these callbacks are received in a function called onreadystatechange.

ajax.onreadystatechange = function() {
    //
};

Now we have to respond only if the request is successful. In this onreadystatechange function, we have 3 variables readyState, status and responseText.

  • readyState will have value 4 when the request is done/completed.
  • status will have value 200 when everything goes right.
ajax.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
    	console.log(this.responseText);
    }
};

Save file on server – PHP

Now create a new file named upload.php and open it in code editor. In this file, we will just be storing the file in a server. Paste the following code in upload.php file:

<?php
    move_uploaded_file($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);
    echo "Done";
?>

At this point if you run the index.php file, you will be able to select a file and save it in your server and your index.php will look like this:

<form method="POST" enctype="multipart/form-data" onsubmit="return onSubmit();">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" />
</form>

<script>
    function onSubmit() {
        var file = document.getElementById("file").files[0];

        var formData = new FormData();
        formData.append("file", file);
        
        var ajax = new XMLHttpRequest();
        ajax.open("POST", "upload.php", true);
        ajax.send(formData);

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

        return false;
    }
</script>

And your upload.php should look like this:

<?php
    move_uploaded_file($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);
    echo "Done";
?>

Show progress bar

Now, in order to view the progress bar you can simply create an <progress> tag anywhere in your index.php where you want to see the progress. Provide it a unique id and set it’s initial value to 0:

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

Get progress bar object in javascript, right above return false; line in the function onSubmit(), like this:

function onSubmit() {
    ..........

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

    var progress = document.getElementById("progress");
    return false;
}

While uploading files, ajax object also has an event called onprogress that will tell the current uploaded file percentage:

ajax.upload.onprogress = function (event) {
    //
};
  • event variable will tell the current status of uploaded file.

First you have to set the maximum value of progress object to that required by an AJAX request to upload the file:

progress.max = event.total;

Now simply set the progress value attribute to uploaded value from event object:

progress.value = event.loaded;

Now, you will be able to view the progress of an uploaded file via AJAX.

Complete code

Here is a complete code of your index.php file:

<form method="POST" enctype="multipart/form-data" onsubmit="return onSubmit();">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" />
</form>

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

<script>
    function onSubmit() {
        var file = document.getElementById("file").files[0];

        var formData = new FormData();
        formData.append("file", file);
        
        var ajax = new XMLHttpRequest();
        ajax.open("POST", "upload.php", true);
        ajax.send(formData);

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

        var progress = document.getElementById("progress");
        ajax.upload.onprogress = function (event) {
            progress.max = event.total;
            progress.value = event.loaded;
        };

        return false;
    }
</script>

Show progress of download with remaining time – Javascript

[wpdm_package id=’104′]

Get data from database using AJAX, Javascript, PHP, MySQL

By the end of this tutorial, you will be able to get data from database using AJAX using simple Javascript (no jQuery). Benefits of using AJAX are:

  1. Page loads faster as there will be no PHP script running during page load.
  2. If you want to change data, you can do that easily without having to refresh the page.
  3. You can show the same data on multiple pages, without having to rewrite the query. Just call the same javascript function.

Where AJAX is used ?

Google Earth

When you scroll in Google Earth, an AJAX request is sent to get the images of new location.

Facebook

When you scroll at the end of page in Facebook, an AJAX request is sent to get the older posts.

Charts & Graphs

In charts, when you change the date value, the charts has been updated to selected date via AJAX.

We are going to show records of employees from database table. We are using database named classicmodel, it will be included in the source files.

Create an HTML table

First we are going to create a file to show the data from database called index.php

Create a simple HTML table and give a unique ID to <tbody> tag

<table>
    <tr>
	<th>First name</th>
	<th>Last name</th>
	<th>Job title</th>
    </tr>

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

Call AJAX to get data from database

To call an AJAX to get the data, first create an built-in XMLHttpRequest object and save in variable ajax.

<script>
    var ajax = new XMLHttpRequest();
</script>

Now call open(method, url, async) function from ajax object.

ajax.open("GET", "data.php", true);
  • First parameter is the method of request GET or POST.
  • Second is the name of file from where to get data. In this case data.php which will be created in next step.
  • Third is a boolean, whether the request is asynchronous or not. true for asynchronous. Asynchronous requests does not hang up the browser. Syncronized requests may block the browser if the script at data.php is very time-taking.

You can also send headers with your request using the following methods:

ajax.setRequestHeader("Accept", "application/json")
ajax.setRequestHeader("Authorization", "Bearer {token}")

You can pass as many headers as you want by calling the method setRequestHeader multiple times.

Call the send() function from ajax object to actually call an AJAX request. It accepts no parameter.

ajax.send();

ajax object has multiple functions that are called once the status of request is changed. For example, when server receives the request, if server does not exists, if server failed to respond etc. All these callbacks are received in a function called onreadystatechange.

ajax.onreadystatechange = function() {
    //
};

Now we have to respond only if the request is successful. In this onreadystatechange function, we have 3 variables readyState, status and responseText.

  • readyState will have value 4 when the request is done/completed.
  • status will have value 200 when everything goes right.
ajax.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
    	console.log(this.responseText);
    }
};

Get data from MySQL database using PHP

Now create a new file named data.php and open it in code editor. First, you have to connect with database:

<?php
$conn = mysqli_connect("localhost", "root", "", "classicmodels");
  • root is the name of database user.
  • Third parameter is the password of database. For XAMPP/WAMP, it will be an empty string.
  • classicmodels is the name of database.

Now, write your query to get the records from database. In my case, I am just getting all employees from database table named employees:

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

Create an array and loop through all database records returned from previous query, and save those records in that array:

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

Now, whatever you echo will returned to the AJAX callback function in index.php file. In case of an array, you have to convert the array into JSON format and then echo it.

echo json_encode($data);
exit();
  1. exit(); will prevent the code from further executing.

    At this point, if you run the index.php file, you will see similar to the following in your browser console:

Now, go back to index.php file and convert this JSON string back into an array:

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

JSON string should now be converted into an Javascript object named data.If you run index.php now and see the browser console, you will see something similar to the following:

json-to-object

Show data in HTML table

You got the data, now you just have to append it in table. Create an empty string variable named html:

var html = "";

Loop through all employees list:

for(var a = 0; a < data.length; a++) {
    //
}

Inside the loop, append the data in html variable:

for(var a = 0; a < data.length; a++) {
    var firstName = data[a].firstName;
    var lastName = data[a].lastName;
    var jobTitle = data[a].jobTitle;

    html += "<tr>";
        html += "<td>" + firstName + "</td>";
        html += "<td>" + lastName + "</td>";
        html += "<td>" + jobTitle + "</td>";
    html += "</tr>";
}

After the loop, append the html variable in <tbody> tag:

document.getElementById("data").innerHTML += html;

Now, your index.php file should look like this:

<table>
    <tr>
	<th>First name</th>
	<th>Last name</th>
	<th>Job title</th>
    </tr>

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

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

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

            var html = "";
            for(var a = 0; a < data.length; a++) {
                var firstName = data[a].firstName;
                var lastName = data[a].lastName;
                var jobTitle = data[a].jobTitle;

                html += "<tr>";
                    html += "<td>" + firstName + "</td>";
                    html += "<td>" + lastName + "</td>";
                    html += "<td>" + jobTitle + "</td>";
                html += "</tr>";
            }
            document.getElementById("data").innerHTML += html;
        }
    };
</script>

And your data.php file should be like this:

<?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);
exit();

Run the index.php file and you will see your data will be displayed via AJAX. So that’s how you can get data from the database using AJAX and display it in an HTML table.

There is more

This is just to get the data from the database. Follow this tutorial to learn complete CRUD (Create, Read, Update and Delete) operation in AJAX.

[wpdm_package id=’93’]

How to resize an image without stretching – PHP

In order to resize an image without stretching, we will be calling built-in functions of PHP. No third party library will be used in this tutorial.

Resizing an image without stretching involves setting the new dimension of an image. You cannot decide both (width & height) of an image in order to resize without stretching. You will only tell the new dimension and this script will resize the image by maintaining its aspect ratio.

Get image and dimension

<form method="POST" action="resize.php" enctype="multipart/form-data">
    <p>
        <input type="file" name="file" onchange="onFileSelected();" id="image" accept="image/*" required="">
    </p>

    <p>
        <input type="number" name="enter_dimension" required="">
    </p>
    <input type="submit" name="submit">
</form>
  • enctype=”multipart/form-data” and method=”POST” are important in <form> tag
  • accept=”image/*” in <img> tag will allow you to view only images. Other documents will automatically be hidden.
  • onchange=”onFileSelected();” in <img> tag will be used to view the image before resizing (just for confirmation)

Show image preview

<img src="" id="preview">

<script type="text/javascript">
function onFileSelected() {
    var image = document.getElementById("image").files;
    if (image.length == 0) {
        console.log("Please select an image");
        return;
    }
    image = image[0];

    var reader = new FileReader();
    reader.onload = function (e) {
        document.getElementById('preview').setAttribute('src', e.target.result);
    }
    reader.readAsDataURL(image);
}
</script>

At this point, you will have something similar to the following:

Resizing image

Create a new file named “resize.php” (or it should be same as <form> tag action=”” attribute in step 1). First, you have to get the input dimension and user selected image:

<?php                        
$dimension = $_POST["enter_dimension"];                    
$file_name = $_FILES["file"]["tmp_name"];
    
$image_size = getimagesize($file_name);                        
$width = $image_size[0];    
$height = $image_size[1];
            
$ratio = $width / $height;                        
if ($ratio > 1)            
{
    $new_width = $dimension;
    $new_height = $dimension / $ratio;            
}            
else                        
{
    $new_height = $dimension;                    
    $new_width = $dimension * $ratio;            
}
                        
$src = imagecreatefromstring(file_get_contents($file_name));                        
$destination = imagecreatetruecolor($new_width, $new_height);

imagecopyresampled($destination, $src, 0, 0, 0, 0, $new_width, $new_height, $width, $height);                        
imagepng($destination, $file_name);
        
imagedestroy($src);                        
imagedestroy($destination);
            
move_uploaded_file($file_name, $_FILES["file"]["name"]);                        
echo "<img src='" . $_FILES["file"]["name"] . "' />";

Explanation

  • getimagesize: This function returns an array containing the width and height of the image.
  • imagecreatefromstring: It creates a new image from image file data.
  • imagecreatetruecolor: It just accepts width and heigth as parameters. And return the true color of the image.
  • imagecopyresampled: This function copies the image from source to destination. And also resize the image with provided width and height.
  • imagepng: This outputs the PNG image to the browser if the 2nd parameter is not provided. But since we provided the 2nd parameter, so it will save the image in a separate PNG file.
  • imagedestroy: Simply destroys the image object.

[wpdm_package id=’81’]

Send dynamic email from HTML & CSS template – PHP

By the end of this tutorial, you will be able to send a dynamic email in PHP. Along with any beautifully designed template in HTML, CSS or Bootstrap. We will be using the template named “Invoice” from this website:
https://www.dyspatch.io/resources/templates/airmail/

It’s a pretty basic template and great to learn.
After downloading the template, you will see something like this:

All are static values. So let’s make them dynamic.

First you have to put all the template code in 1 separate file and named it “payment.php”, make sure to have all CSS code in this file. No external CSS file should be used because it will not appear in email.

Now, you have to replace the values you want to change and replace them with {{key}} for example, if you want to make coupon code dynamic, you will do something like this:

Coupon code {{coupon_code}}

Now, coming back to the file from where you want to send email, let’s say “send-mail.php”, first you have to get the template file by:

<?php
    $email = file_get_contents("payment.php");
    echo $email;
?>

This will display your email template in “send-mail.php” file. In order to replace the {{coupon_code}} with your dynamic value, you have to use the str_replace function of PHP. It accepts 3 parameters:

  1. Value to be replaced
  2. New value
  3. String from which to replace
<?php
    $email = file_get_contents("payment.php");
    $email = str_replace("{{coupon_code}}", "1234567", $email);
    echo $email;
?>

Now we are going to add {{key}} on every static value in template which needs to be dynamic. After that, you need to create an array in your “send-mail.php” file and use the same function for all static values.

<?php
    $email = file_get_contents("payment.php");
    $email = str_replace("{{coupon_code}}", "1234567", $email);
    $variables = array(
        "{{coupon_code}}" => 1234,
        "{{invoice}}" => 5678,
        "{{card_ending}}" => 9876,
        "{{username}}" => "Adnan"
   );

    foreach ($variables as $key => $value)
        $email = str_replace($key, $value, $email);
    echo $email;
?>

Now, you will be able to see your template with correct values. You can send the mail using the following 2 methods:

  1. PHP built-in mail() function
  2. Using PHPMailer library

Built-in mail() function

You can call the function:

<?php
    // Your subject goes here
    $subject = 'Payment Invoice';

    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

    // Enter receiver's email address
    mail("receiver_email@gmail.com", $subject, $email, $headers);
?>

Using PHPMailer library

You can install the library using composer in your project:

composer require phpmailer/phpmailer

and follow the guide from here: https://github.com/PHPMailer/PHPMailer


If you do not want to use composer, you can download manually from the following link and follow the guide: https://github.com/adnanafzal565/php-mailer

Hit the “send mail” button and you will receive an email similar to this:

So that’s how you can send a dynamic email in PHP from any HTML template. Also, learn how you can attach a link to the file to download in an email from here.

If you have any problems in following this, feel free to ask in the comments section below.

[wpdm_package id=’76’]

How to upload single and multiple images in iOS Swift, PHP and MySQL

In this article, we will discuss how you can upload single or multiple images from your iOS app in Swift, and save them in the MySQL database.

Solution for Swift UI

If you are developing your app in Swift UI, please follow this post.

When developing iOS applications, one of the most common features in almost all apps is to upload images. It can be in the form of a profile picture, or payment receipt or anything. Swift provides a built-in method to allow developers to add functionality. There users can select an image from their photo library. However, to upload multiple images, there is no built-in method in Swift at the time of writing this. But we have external libraries that allow users to pick multiple images.

Save image from iOS app

When it comes to saving the image in the database, there are again multiple choices. You can either convert the image in an encoded base64 string or you can send an image entirely as multipart. The second choice is not very often used because it has some drawbacks. The major one of them is that the image with very high quality and large size are unable to transfer. So we will choose the first method i.e. to convert an image into an encoded base64 string.

1. Single image upload

In this method, no external library has been used. All the functions required to select single image from gallery are already provided by Swift. We just need to implement 2 delegates UIImagePickerControllerDelegate and UINavigationControllerDelegate to our view controller that will be responsible to open the screen to gallery and also to return the selected image. We have created a simple button which when clicked will open the UIImagePickerController in current view controller. imagePickerController this is a delegate function present in UIImagePickerControllerDelegate that will return the selected image from photo library. We are displaying that image in our UIImageView for confirmation, and also to send to the server. Because we can convert an image to base64 string using its UIImageView object.

Then we are creating a button which when clicked will convert the image to base64 string and send the request to the server. For sending an HTTP request, you also have many choices, for example, you can use the Alamofire library. But to keep things simple, we are using Swift’s built-in NSURLConnection class. Before sending the request we are also displaying a loading dialog and when the response is received from the server, we are simply displaying an alert that the image has been uploaded.

Swift iOS

import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    private var image: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let btnSelectImage: UIButton = UIButton(frame: CGRect(x: 30, y: 100, width: view.frame.size.width - 60, height: 30))
        btnSelectImage.setTitle("Select image", for: .normal)
        btnSelectImage.setTitleColor(UIColor.systemBlue, for: .normal)
        btnSelectImage.contentHorizontalAlignment = .center
        btnSelectImage.addTarget(self, action: #selector(selectImage), for: .touchUpInside)
        view.addSubview(btnSelectImage)
        
        image = UIImageView(frame: CGRect(x: 30, y: btnSelectImage.frame.origin.y + btnSelectImage.frame.size.height + 30, width: 300, height: 300))
        image.clipsToBounds = true
        image.contentMode = .scaleAspectFill
        view.addSubview(image)
        
        let btnUpload: UIButton = UIButton(frame: CGRect(x: 30, y: image.frame.origin.y + image.frame.size.height + 30, width: view.frame.size.width - 60, height: 40))
        btnUpload.setTitle("Upload to server", for: .normal)
        btnUpload.backgroundColor = UIColor.systemGreen
        btnUpload.setTitleColor(UIColor.white, for: .normal)
        btnUpload.addTarget(self, action: #selector(uploadToServer), for: .touchUpInside)
        btnUpload.layer.cornerRadius = 5
        view.addSubview(btnUpload)
    }
    
    @objc private func uploadToServer(sender: UITapGestureRecognizer) {
        let imageData: Data = image.image!.pngData()!
        let imageStr: String = imageData.base64EncodedString()

        let alert = UIAlertController(title: "Loading", message: "Please wait...", preferredStyle: .alert)
        present(alert, animated: true, completion: nil)

        let urlString: String = "imageStr=" + imageStr
        
        var request: URLRequest = URLRequest(url: URL(string: "http://172.20.10.2:8888/tutorials/single-multiple-image-upload/index.php")!)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        request.httpBody = urlString.data(using: .utf8)

        NSURLConnection.sendAsynchronousRequest(request, queue: .main, completionHandler: { (request, data, error) in

            guard let data = data else {
                return
            }

            let responseString: String = String(data: data, encoding: .utf8)!
            print("my_log = " + responseString)

            alert.dismiss(animated: true, completion: {

                let messageAlert = UIAlertController(title: "Success", message: responseString, preferredStyle: .alert)
                messageAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!) in
                    //
                }))

                self.present(messageAlert, animated: true, completion: nil)
            })
        })
    }
    
    @objc private func selectImage(sender: UITapGestureRecognizer) {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self as! UIImagePickerControllerDelegate & UINavigationControllerDelegate
        imagePicker.sourceType = UIImagePickerController.SourceType.photoLibrary
        imagePicker.allowsEditing = false
        present(imagePicker, animated: true, completion: nil)
    }
    
    @objc func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let chosenImage = info[UIImagePickerController.InfoKey.originalImage.rawValue] as! UIImage
        image.image = chosenImage
        dismiss(animated: true, completion: nil)
    }

}

PHP & MySQL

Make sure to change the server path with yours. If you are working on localhost, you can get your IP address by command prompt or terminal and running the command: ifconfig. In our PHP file, we are first receiving base64 string in a variable and then creating a path where the image will be stored. We need to create a folder named “images” in our server’s root folder.

Then we need to decode that base64 string into actual image file, so remove the base64 data part from a string, replace all empty spaces with + sign, and then decoding the base64 string, and finally saving the file in the images folder. We also need to save that file’s reference in our database, so we are simply making a connection with MySQL database and running an INSERT query to save the path of the image. Then we are sending the response as a string back to the iOS app. Make sure to change the database credentials as well as per your server.

<?php

$picture = $_POST["imageStr"];
$folder_path = "images/" . time() . ".png";

$data = str_replace('data:image/png;base64,', '', $picture);
$data = str_replace(' ', '+', $data);
$data = base64_decode($data);
file_put_contents($folder_path, $data);

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

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

echo "Image has been uploaded";

?>

2. Multiple image upload

As discussed earlier, we need to use an external library to implement multiple image features in our iOS app. So we are going to use a library called BSImagePicker. It will be installed in our project using Cocoa pods, first, you need to initialize it. Open command prompt or terminal in your project’s root folder and run the following command:

pod init

This will create a Podfile (without any extension) in your project’s root folder. Open that file and include the library like the following, your project name could be different of course:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'MultipleImageUpload' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for MultipleImageUpload
  pod "BSImagePicker", "~> 3.1"

end

Now run the command

pod update

to install the library. Once installed, close the project if already opened and now run the project using XCode but with the file ending with “.xcworkspace” NOT “.xcodeproj”. Now accessing the library requires user permission so open your “info.plist” file as source code and paste the following lines at the end of dict tag:

<key>NSPhotoLibraryUsageDescription</key>
<string>Why you want to access photo library</string>

Now open your view controller file and first import 2 files named BSImagePicker and Photos. When user select multiple images we can also show them in a collection view for a better user experience, for that purpose we need to implement 2 delegates, UICollectionViewDelegate and UICollectionViewDataSource. Creating a global variable for collection view so it can be accessible throughout the view controller class, colleection view has multiple cells and each cell has its own identifer and a class. For cell, we have created a class named ImageCell and it has only an image view because that is all we needed here.

Swift iOS

import UIKit

import BSImagePicker
import Photos

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
    
    private var collectionView: UICollectionView!
    private let identifier: String = "identifier"
    private var selectedImages: [UIImage] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let btnSelectImage: UIButton = UIButton(frame: CGRect(x: 30, y: 100, width: view.frame.size.width - 60, height: 30))
        btnSelectImage.setTitle("Select images", for: .normal)
        btnSelectImage.setTitleColor(UIColor.systemBlue, for: .normal)
        btnSelectImage.contentHorizontalAlignment = .center
        btnSelectImage.addTarget(self, action: #selector(selectImages), for: .touchUpInside)
        view.addSubview(btnSelectImage)
        
        let flowLayout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        flowLayout.minimumLineSpacing = 10
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumInteritemSpacing = 10
        flowLayout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        flowLayout.itemSize = CGSize(width: 300, height: 300)

        collectionView = UICollectionView(frame: CGRect(x: 0, y: btnSelectImage.frame.origin.y + btnSelectImage.frame.size.height + 30, width: view.frame.size.width, height: 300), collectionViewLayout: flowLayout)
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.backgroundColor = UIColor.clear.withAlphaComponent(0)
        collectionView.alwaysBounceHorizontal = true
        collectionView.register(ImageCell.self, forCellWithReuseIdentifier: identifier)
        view.addSubview(collectionView)
        
        let btnUpload: UIButton = UIButton(frame: CGRect(x: 30, y: collectionView.frame.origin.y + collectionView.frame.size.height + 30, width: view.frame.size.width - 60, height: 40))
        btnUpload.setTitle("Upload to server", for: .normal)
        btnUpload.backgroundColor = UIColor.systemGreen
        btnUpload.setTitleColor(UIColor.white, for: .normal)
        btnUpload.addTarget(self, action: #selector(uploadToServer), for: .touchUpInside)
        btnUpload.layer.cornerRadius = 5
        view.addSubview(btnUpload)
    }
    
    @objc private func uploadToServer(sender: UITapGestureRecognizer) {
        let alert = UIAlertController(title: "Loading", message: "Please wait...", preferredStyle: .alert)
        present(alert, animated: true, completion: nil)

        var imageStr: [String] = []
        for a in 0..<self.selectedImages.count {
            let imageData: Data = self.selectedImages[a].jpegData(compressionQuality: 0.1)!
            imageStr.append(imageData.base64EncodedString())
        }

        guard let data = try? JSONSerialization.data(withJSONObject: imageStr, options: []) else {
            return
        }

        let jsonImageString: String = String(data: data, encoding: String.Encoding.utf8) ?? ""
        let urlString: String = "imageStr=" + jsonImageString

        var request: URLRequest = URLRequest(url: URL(string: "http://172.20.10.2:8888/tutorials/single-multiple-image-upload/multiple.php")!)
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        request.httpBody = urlString.data(using: .utf8)

        NSURLConnection.sendAsynchronousRequest(request, queue: .main, completionHandler: { (request, data, error) in

            guard let data = data else {
                return
            }

            let responseString: String = String(data: data, encoding: .utf8)!
            print("my_log = " + responseString)

            alert.dismiss(animated: true, completion: {
                let messageAlert = UIAlertController(title: "Success", message: responseString, preferredStyle: .alert)
                messageAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action: UIAlertAction!) in
                    //
                }))
                self.present(messageAlert, animated: true, completion: nil)
            })
        })
    }
    
    @objc private func selectImages(sender: UITapGestureRecognizer) {
        let imagePicker = ImagePickerController()
        presentImagePicker(imagePicker, select: { (asset) in
        }, deselect: { (asset) in
            
        }, cancel: { (assets) in
            
        }, finish: { (assets) in
            
            self.selectedImages = []
            let options: PHImageRequestOptions = PHImageRequestOptions()
            options.deliveryMode = .highQualityFormat

            for asset in assets {
                PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: options) { (image, info) in
                    self.selectedImages.append(image!)
                    self.collectionView.reloadData()
                }
            }
        })
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return selectedImages.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let data: UIImage = selectedImages[indexPath.item]
        let cell: ImageCell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as! ImageCell
        cell.image.image = data
        return cell
    }


}

class ImageCell: UICollectionViewCell {
    var image: UIImageView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupViews()
    }
    
    private func setupViews() {
        image = UIImageView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
        image.clipsToBounds = true
        image.contentMode = .scaleAspectFill
        addSubview(image)
    }
}

PHP & MySQL

As we are sending multiple images in base64 string. So, we have to loop through all and save them one-by-one in the server as well as in MySQL database. The code for this is pretty much same as the previous file.

<?php

$conn = mysqli_connect("localhost:8889", "root", "root", "tutorials");
$imageStr = json_decode($_POST["imageStr"]);

for ($a = 0; $a < count($imageStr); $a++)
{
	$folder_path = "images/" . $a . "-" . time() . ".png";

	$picture = $imageStr[$a];
	$data = str_replace('data:image/png;base64,', '', $picture);
	$data = str_replace(' ', '+', $data);
	$data = base64_decode($data);

	file_put_contents($folder_path, $data);

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

echo "Image has been uploaded";

?>

So that’s how you can upload single or multiple images from your iOS app in Swift, and save them in the MySQL database.

[wpdm_package id=’62’]