PHP CONT 2021

images used in this lecture

In continuing from the GET request, we will now turn to the POST request.
We will do a live example: whereby we will create an html form,send the data to PHP via the POST method and subsequently write the code to process the form data in php. The purpose of this “app” is to create an online gallery of graffiti art from different geographic locations. An online gallery is not super interesting – but it is a good exercise within the context for learning how to process a form, store the data in a database and finally display filtered results.

Create the Form and do Preliminary Processing

First, we will focus on creating the form and doing some preliminary processing.
Our HTML form will take input data from the user regarding the artwork that they want to submit to the system.
Creating the input form:
Let us start with a new PHP page .
Then, using the following example, create an HTML form that will let the user enter the required information.
This file should be saved as insertForm.php in your project directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html>
<head>
<title>Sample Insert into Gallery Form </title>
<!--set some style properties::: -->
<link rel="stylesheet" type="text/css" href="css/galleryStyle.css">
</head>
<body>
<div class= "formContainer">
<!--form done using more current tags... -->
<form action="insertForm.php" method="post" enctype ="multipart/form-data">
<!-- group the related elements in a form -->
<h3> SUBMIT AN ART WORK :::</h3>
<fieldset>
 <p><label>Artist:</label><input type="text" size="24" maxlength = "40" name = "a_name" required> </p>
<p><label>Title:</label><input type = "text" size="24" maxlength = "40"  name = "a_title" required></p>
<p><label>Geographic Location:</label><input type = "text" size="24" maxlength = "40" name = "a_geo_loc" required></p>
<p><label>Creation Date (DD-MM-YYYY):</label><input type="date" name="a_date" required></p>
<p><label>Description:</label><textarea type = "text" rows="4" cols="50" name = "a_descript" required></textarea></p>
<p><label>Upload Image:</label> <input type ="file" name = 'filename' size=10 required/></p>
<p class = "sub"><input type = "submit" name = "submit" value = "submit my info" id =buttonS /></p>
 </fieldset>
</form>
</div>
</body>
</html>

Note: in the head tag we have a link tag containing a link to a style sheet called galleryStyle.css. This style sheet will contain all the formatting/ style definitions for the form and the resulting output (to come later).
You may define your own styles and save it in the project directory as galleryStyle.css. Alternatively you may use the following style definitions provided below – again please save in a file called galleryStyle.css in the project folder in a new folder called css.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* css for the initial form*/
label{display:inline-block; width:30%;font-size:1vw; font-weight: bold; align: center; margin-top:1%;}
textarea{vertical-align: top;width:50%;margin-left:2%;}
input{margin-left:2%;width:50%;}
fieldset{background-color:#38B4FC;width:50%;color:#555;font-family:arial;margin:0 auto;margin-top:2%;}
#buttonS{margin:0;width:auto;font-size:1vw;}
.sub{background:#8AD3FD;padding:2%;}
h3{text-align: center; width:50%;font-family:arial;color:#555;margin:0 auto; margin-top:5%;}
 
 
/* css for displaying the output*/
.outer h3{font-size:16px;color:#555;font-family:arial;font-style:bold;}
.outer{background-color:#3ad7ff;margin:0 auto;margin-top:2%;padding-bottom:2%; width:50%;overflow:hidden;}
.content{background-color:#CF8AEC;width:75%; margin:0 auto;padding:2%; margin-top:1%;}
.content p{padding:2%;background:#E0C9E9;font-family:arial;}
img{margin:2%;width:96%;}

We have implemented very rudimentary form validation by specifying the required attribute for all input fields. Adding the “required” attribute ensures that the user must input some sort of data in each field, in order for the submit button to function (send data to the server…)

The attributes in the form tag are very important: <form action=”insertForm.php” method=”post” enctype =”multipart/form-data”>:

  • action has the value for the url (insertForm.php) – which is the page to which the data will be sent to (there will be php code within this page to deal with the “posted” data).
  • method is the protocol by which the data will be sent (in this case the data is “posted”).
  • enc-type is the final attribute which specifies the content-type to use when submitting the form. “multipart/form-data” is used when a form requires binary data, like the contents of a file, to be uploaded (which is what we will do as we are sending an image as well as text).

Now the “html” (user input) section is complete, we will create the php code which will process the HTML form information.

First though: run the page – fill out the form and click submit -> you can already see with the help of the browser inspector that a POST request was made successfully …

PHP CODE TO PROCESS FORM DATA:

  • In the same page: insertForm.php, we first need to check if data has been posted to the server (by the user clicking the submit button) and if yes – then we want to process the data from the form. Otherwise we do nothing until there is something posted.
    There is one in-built PHP variable which allows us to check if there is data waiting:$_SERVER: this is an associative array, which has a “key” called REQUEST_METHOD.
    If the value associated with this key is equal to POST then we know that there is data to process (all of these keywords are inbuilt into the PHP language).
    So we use an if statement which will execute a block of code if the boolean expression equates to true.
    The following code sets up this if statement: Place the following at the TOP of the PHP page … (just as we did with the GET request last week … )

    1
    2
    3
    4
    5
    6
    7
    
    <?php
    //check if there has been something posted to the server to be processed
    if($_SERVER['REQUEST_METHOD'] == 'POST')
    {
    // need to process
    }
    ?>
  • Next, we will write the code for processing the input: within the if clause:
    We want to get the artist, piece title, location, description and creation date inputs that are specified in the HTML form (by the name attribute of each input element).The inbuilt $_POST Associative array will automatically contain the values of these input fields.
    How? ** (Review from last week )**
    When the submit my info button is clicked, the values for each of the input fields except “filename” are stored automatically in this array, which is then submitted (posted) to the insertForm.php web page. PHP has access to the submitted $_POST associative array.
    The key for each value in the array is the value of the attribute called name specified in each form input field in the html form.
    Thus, in the insertForm.php page, the correct way to get this information is to create five new variables, $artist, $title, $loc … (one for each input field and you can call them what you want) and set them equal to the values that have been “posted”.
    Copy the following into the page – underneath “// need to process”.

    1
    2
    3
    4
    5
    
     $artist = $_POST['a_name'];
     $title = $_POST['a_title'];
     $loc = $_POST['a_geo_loc'];
     $description = $_POST['a_descript'];
     $creationDate = $_POST['a_date'];
  • OK – so before continuing lets put in the following echo statement after the $creationDate …

    1
    
     echo("ARTIST NAME FROM SERVER POST ARRAY :: ".$artist);

    Now run the page -> fill out the form and submit: you should have the echo statement written back to the page successfully …

  • The image has been automatically uploaded to the server to a temporary location, and is accessible via another SuperGlobal PHP variable :- a two dimensional associative array called $_FILES:
    When the file is uploaded, we can access the file in the $_FILES array by using the “name” attribute from the html form: “filename” as the key for the 1st dimension in the array.
    For each element in the $_FILES array, the 2nd dimension contains INBUILT properties assigned when the file is initially uploaded to the server.
    The ones we care about for now are::
    The key: tmp_name which contains the path where the image has been initially uploaded.
    The key: name which contains the actual name of the file.
    Let’s first then verify that when we click on the submit button that the file has been uploaded to a temporary location. Copy the code below directly below the previously inserted code (within the outer IF statement) ** also be sure to comment out the echo statement **:

    1
    2
    3
    4
    5
    6
    
    // check that there is a FILES ARRAY
    	if($_FILES)
    	{
      	echo "file name: ".$_FILES['filename']['name'] . "<br>";
      	echo "path to file uploaded: ".$_FILES['filename']['tmp_name']. "<br>";
    	}
  • Now if you run the php page and fill out the form (especially select an image from anywhere on your machine), then press the submit button – you should find that the path where the file has been uploaded to as well as the correct file name are “echoed” back to you…

  • If we have reached this point, we know that the file has been uploaded – however we would like to move the uploaded file from the temporary location to a more permanent one. This is done using the inbuilt move_uploaded_file function, passing the file in the temporary location to the new location, which will be a place where you can access it easily.
    1: The first step is to assign the filename (from the $_FILES array) into a variable called i.e. $fname. This is useful as from now on, we can use this variable in different contexts.
    2: The next step is to create a directory in the project folder to hold the uploaded image(s): So create a folder called “images” at the root of the project directory.
    3: We can now specify the move_uploaded_file() function with the necessary arguments: the source path and the destination path.
    Copy the following code directly below the previously inserted echo statements:

    1
    2
    3
    
    $fname = $_FILES['filename']['name'];
    move_uploaded_file($_FILES['filename']['tmp_name'], "images/".$fname);
    echo "<br>Stored in: " . "images/" .$fname."<br>";
  • Now if you run the page, select an image to upload and press the submit button: you will find another echo statement specifying the path of where the file has moved.
    Also, you should look in your images folder to verify that the file is now there ….
    Note:: the file uploaded need NOT be an image -> it could be any file type (video, audio, pdf…) – you as the developer would just need to verify the file type.

  • Finally we just want to echo the data that we just processed back to the screen.
    Copy the following statements and place them directly underneath the statements you just inserted (still within the if clause):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
          echo "<div class = 'outer'>";
          echo "<h3> Results from user </h3>";
          echo "<div class ='content'>";
          echo "<p> Artist:: ".$artist."</p>";
          echo "<p> Title:: ".$title."</p>";
          echo "<p> Location:: ".$loc."</p>";
          echo "<p> Description:: ".$description."</p>";
          echo "<p> Creation Date:: ".$creationDate."</p>";
          echo "<img src ='images/".$fname."'\>";
          echo "</div>";
          echo "</div>";

That’s it! Now you have implemented the functionality to take user input, process the input with PHP and for now we output the data & image (or video, audio …) back to the browser.
Note: what happens when you try to refresh the page or press the back button? The browser will by default want re-submit the data to the php page no matter what you do.
The browser will ask the user if that’s what they want – but if they don’t, they cannot refresh the page (though one can reload the page). We would like to resolve this situation … as it is potentially dangerous.
We could send the data via a GET request – however we know that POST is more secure and we still want to be able to send multipart form data…

There is a simple and effective solution that is very common in web applications: called the Post/Redirect/Get pattern.
Effectively we need to:
1: POST the data to the server and do preliminary processing on the data
2: REDIRECT (reload) the page -> effectively clearing the headers in the HTML page
3: GET the data to be sent back and displayed to the HTML page.
It’s typical for all forms to do a POST request, then if successful, you should do a redirect BEFORE displaying the data… But how? Don’t we lose the data that we just posted?

Well – we need to use another PHP structure: PHP Session Variables. We will discuss these briefly first and then come back to our initial issue:

SESSIONS

A session in php is a way to store information (in variables) to be used across multiple pages.
By default, session variables last until the user closes the browser.
Session variables will hold information about a SINGLE user (the user that just posted the request to retrieve the page)
Starting a session:
A session is started with the session_start() function.
Session variables are set with another PHP global variable – Associative array): $_SESSION. This is another inbuilt PHP Associative Array. You access / store any given variable through the key/value pair convention.
Now, let’s create a new page called sessionTest.php. In this page, we start a new PHP session and set some session variables:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
// Start the session
session_start();
?>
<html>
<body>
<?php
echo "My session id: ".session_id()."<br>";
// Set session variables
$_SESSION["favColor"] = "light-blue";
$_SESSION["favAnimal"] = "iguana";
echo "Session variables are set.";
?>
</body>
</html>

Run the page ->
First we use the method to start a session
Then we use the inbuilt _$SESSION variable to set the key/value pairs that we want.
SO how does PHP know that this particular session belongs to a specific user?
Most sessions set a user-key on the person’s computer. Then, when a session is opened on another page, it scans the computer for a user-key. If there is a match, it accesses that session, if not, it starts a new session.
Access Session variables:
Lets put this into practice by accessing our session variables in another page:
Create a new php page called “sessionTestGet.php” and insert the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
session_start();
?>
<html>
<body>
<?php
echo "My session id: ".session_id()."<br>";
// Echo session variables that were set on previous page
echo "Favorite color is " . $_SESSION["favColor"] . ".<br>";
echo "Favorite animal is " . $_SESSION["favAnimal"] . ".".".<br>";
//output the array
var_dump($_SESSION);
?>
</body>
</html>

Run the page -> Well now we have the session variables available to use…
Modifying Session Variables
We can also change the values of different session variables / or add new pairs as in the following example (create a new page):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
session_start();
?>
<html>
<body>
<?php
echo "My session id: ".session_id()."<br>";
// to change a session variable, just overwrite it
$_SESSION["favColor"] = "red";
$_SESSION["favFood"] = "lasagna";
var_dump($_SESSION);
?>
</body>
</html>

Add the following to SessionTestGet.php and run the page again …

1
echo "Favorite animal is " . $_SESSION["favFood"] . ".".".<br>";

And finally at some point we need to destroy the session ….
(for educational purposes lets put this on yet another php page)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
session_start();
?>
<html>
<body>
<?php
echo "My session id: ".session_id()."<br>";
// remove all session variables
session_unset();
// destroy the session
session_destroy();
?>
</body>
</html>

Now -> if you try to access the formerly saved properties they are no longer there….

This was just a preliminary intro to SESSION variables – and it is an extremely useful mechanism for maintaining state across pages…
So let’s come back to our previous POST example … how do session variables fit in:
1: POST the data to the PHP page
2: Process the data and STORE this data in session variables
3: Redirect to the SAME page (could be a different page) – but now the state will be maintained EVEN on reload
4: Retrieve the data from the session variables and echo to the page …
5: Destroy the session…
Create a new php page called insertFormSession.php. It will contain the same form and php processing as well as some new stuff…:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
session_start();
?>
<?php
//check if there has been something posted to the server to be processed
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
// need to process
 $_SESSION['a_name'] = $_POST['a_name'];
 $_SESSION['a_title'] = $_POST['a_title'];
 $_SESSION['a_geo_loc'] = $_POST['a_geo_loc'];
 $_SESSION['a_descript'] = $_POST['a_descript'];
 $_SESSION['a_date'] =$_POST['a_date'];
if($_FILES)
  {
    //echo "file name: ".$_FILES['filename']['name'] . "<br />";
  //  echo "path to file uploaded: ".$_FILES['filename']['tmp_name']. "<br />";
    $fname = $_FILES['filename']['name'];
    move_uploaded_file($_FILES['filename']['tmp_name'], "images/".$fname);
    $_SESSION['a_image'] = $fname;
    //REDIRECT
    header("Location:insertFormSession.php");
    //RETURN ...
    return;
  }
}
?>
<?php
if(isset($_SESSION['a_name'])&&$_SESSION['a_title']&&$_SESSION['a_geo_loc']&&
$_SESSION['a_descript']&&$_SESSION['a_date']&&$_SESSION['a_image']){
 
  $artist =   $_SESSION['a_name'];
  $title = $_SESSION['a_title'];
  $loc = $_SESSION['a_geo_loc'];
  $description = $_SESSION['a_descript'];
  $creationDate = $_SESSION['a_date'];
  $fname = $_SESSION['a_image'];
 
  echo "<br \>Stored in: " . "images/" .$fname."<br \>";
  echo "<div class = 'outer'>";
  echo "<h3> Results from user </h3>";
  echo "<div class ='content'>";
  echo "<p> Artist:: ".$artist."</p>";
  echo "<p> Title:: ".$title."</p>";
  echo "<p> Location:: ".$loc."</p>";
  echo "<p> Description:: ".$description."</p>";
  echo "<p> Creation Date:: ".$creationDate."</p>";
  echo "<img src ='images/".$fname."'\>";
  echo "</div>";
  echo "</div>";
  // remove all session variables
  session_unset();
  //destroy a session
  session_destroy();
 
}
?>
<html>
<head>
<title>Sample Insert into Gallery Form </title>
<!--set some style properties::: -->
<link rel="stylesheet" type="text/css" href="css/galleryStyle.css">
</head>
<body>
<div class= "formContainer">
<!--form done using more current tags... -->
<form action="insertFormSession.php" method="post" enctype ="multipart/form-data">
<!-- group the related elements in a form -->
<h3> SUBMIT AN ART WORK :::</h3>
<fieldset>
 <p><label>Artist:</label><input type="text" size="24" maxlength = "40" name = "a_name" required> </p>
<p><label>Title:</label><input type = "text" size="24" maxlength = "40"  name = "a_title" required></p>
<p><label>Geographic Location:</label><input type = "text" size="24" maxlength = "40" name = "a_geo_loc" required></p>
<p><label>Creation Date (DD-MM-YYYY):</label><input type="date" name="a_date" required></p>
<p><label>Description:</label><textarea type = "text" rows="4" cols="50" name = "a_descript" required></textarea></p>
<p><label>Upload Image:</label> <input type ="file" name = 'filename' size=10 required/></p>
<p class = "sub"><input type = "submit" name = "submit" value = "submit my info" id =buttonS /></p>
 </fieldset>
</form>
</div>
</body>
</html>

**PLEASE NOTE :: the method call header(“Location:insertFormSession.php”); – You need to ensure that you are redirecting to YOUR php page name …
Run the page – and then try refresh — Notice the difference?

Note: We have only implemented very rudimentary form validation using the required attribute in the input tag. You can do more comprehensive form validation on the client side (before submitting the data to the server) using JavaScript. Please refer to the following w3schools link for examples – as we will not go over it in this tutorial.

Submit A Form Without Reloading the Page using JQuery

In this section, we are going to submit the SAME form and DISPLAY the same results, but we will use JQuery and AJAX in order to circumvent the need for page reloading…
Create a new php page and call it InsertGalleryAJAX.php. Also, since we are using JQuery, we need to include the JQuery library in our php page…

HTML MARKUP

As we are starting this example from scratch we first need the static HTML markup:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<html>
<head>
<title>Sample Insert into Gallery Form USING JQUERY AND AJAX </title>
<!-- get JQUERY -->
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!--set some style properties::: -->
<link rel="stylesheet" type="text/css" href="css/galleryStyle.css">
</head>
<body>
  <!-- NEW for the result -->
<div id = "result"></div>
 
<div class= "formContainer">
<!--form done using more current tags... -->
<form id="insertGallery" action="" enctype ="multipart/form-data">
<!-- group the related elements in a form -->
<h3> SUBMIT AN ART WORK :::</h3>
<fieldset>
<p><label>Artist:</label><input type="text" size="24" maxlength = "40" name = "a_name" required></p>
<p><label>Title:</label><input type = "text" size="24" maxlength = "40"  name = "a_title" required></p>
<p><label>Geographic Location:</label><input type = "text" size="24" maxlength = "40" name = "a_geo_loc" required></p>
<p><label>Creation Date (DD-MM-YYYY):</label><input type="date" name="a_date" required></p>
<p><label>Description:</label><textarea type = "text" rows="4" cols="50" name = "a_descript" required></textarea></p>
<p><label>Upload Image:</label> <input type ="file" name = 'filename' size=10 required/></p>
<p class = "sub"><input type = "submit" name = "submit" value = "submit my info" id ="buttonS" /></p>
 </fieldset>
</form>
</div>
<script>
// here we put our JQUERY
</script>
</body>
</html>

Ok – so this is very similar to the previous example EXCEPT:
We left the action attribute of the form empty
We took out the method attribute of the form
We added an id called “insertGallery” to the form
We added a div with id called “result” in order to hold the results….

USE JQUERY TO CAPTURE THE DATA

Instead of automatically sending the form as was done earlier, we will instead use JQuery to access the form data.
First we need to detect when the form is to be submitted -> add the following into the script tags:

1
2
3
4
5
6
7
$(document).ready (function(){
    $("#insertGallery").submit(function(event) {
       //stop submit the form, we will post it manually. PREVENT THE DEFAULT behaviour ...
      event.preventDefault();
     console.log("button clicked");
   });
});

If you now run the page -> and click on the submit button, the line “button clicked” should be output to the console.
If you have not input data into all the required fields, then the initial validation still occurs:: why? – We are STILL using the “submit” event – > which triggers the basic form validation…
Getting the form data
Now we want to access the form data – there are multiple ways of doing this:
1/ Get the value of each field -> this is really long winded and since we want all fields in the form we will find another option:
2/
(a) We will get the form element by its id i.e. let form = $(‘#insertGallery’)[0];
(b) We will use the inbuilt JavaScript FormData object i.e. let data = new FormData(form);
This object can take an HTML form as a parameter upon making a new instance, and will AUTOMATICALLY populate the object with the form’s current keys/values using the name property of each element for the keys and their submitted value for the values. It will also encode file input content.
NICE.

1
2
3
4
5
6
let form = $('#insertGallery')[0];
let data = new FormData(form);
/*console.log to inspect the data */
     for (let pair of data.entries()) {
       console.log(pair[0]+ ', ' + pair[1]);
     }


Ok – so we now have the form data: the next step is to use AJAX to “post the data” to the PHP page.

Use AJAX to POST the data

JQuery has a lovely function called $.ajax(). It is a more general function then the $.json() function that we used previously. It works in much the same way – however you can specify more options. Also it will not automatically convert the response to JSON -> (we will see how to do that in a while…).
Add the following (within the submit event callback handler):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*https://api.jquery.com/jQuery.ajax/*/
     $.ajax({
            type: "POST",
            enctype: 'multipart/form-data',
            url: "insertGalleryAjax.php",
            data: data,
            processData: false,//prevents from converting into a query string
            /*contentType option to false is used for multipart/form-data forms that pass files.
            When one sets the contentType option to false, it forces jQuery not to add a Content-Type header, otherwise, the boundary string will be missing from it.
            Also, when submitting files via multipart/form-data, one must leave the processData flag set to false, otherwise, jQuery will try to convert your FormData into a string, which will fail. */
 
            /*contentType: "application/x-www-form-urlencoded; charset=UTF-8", // this is the default value, so it's optional*/
 
            contentType: false, //contentType is the type of data you're sending,i.e.application/json; charset=utf-8
            cache: false,
            timeout: 600000,
            success: function (response) {
            //response is a STRING (not a JavaScript object -> so we need to convert)
            console.log("we had success!");
            console.log(response);
           },
           error:function(){
          console.log("error occurred");
        }
      });

This function will do the following:
(1) POST the data
(2) understands that it is sending multipart data
(3) specifies the php page that we are posting to (itself) **Make sure this matches your page name **
(4) specified the data to be posted (the formData object)
(5) set processData to false -> is important!
(6) set contentType to false -> multi part form data …
(7) no caching (always send / receive anew)
(8) timeout -> for how long it will try to send
(9) the success function -> here is where we will do something with the data we get back
(10) the error function -> here is where we will do something if the request was not successful.
There are more options that you can specify, but we will move on …

PHP script

Since we are POSTING to a php page -> we need some php to deal with this request!
Add the following AT THE TOP of your php page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
//check if there has been something posted to the server to be processed
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
// need to process
 $artist = $_POST['a_name'];
 $title = $_POST['a_title'];
 $loc = $_POST['a_geo_loc'];
 $description = $_POST['a_descript'];
 $creationDate = $_POST['a_date'];
 if($_FILES)
  {
    //echo "file name: ".$_FILES['filename']['name'] . "<br />";
    //echo "path to file uploaded: ".$_FILES['filename']['tmp_name']. "<br />";
   $fname = $_FILES['filename']['name'];
   move_uploaded_file($_FILES['filename']['tmp_name'], "images/".$fname);
    echo "done";
    exit;
  }//FILES
}//POST
?>

The code here is the same php code as before working with Sessions .. .except now when we echo any data from php it will NOT be output to the page, rather it will be asynchronously received by the success function made available by the Ajax function
Finally – lets just briefly look at ONE solution for packaging data in php as aa JSON string – so that it can not only be received by javascript – but understood as structured data.
Add the following after the move_uploaded_file() …

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 //package the data and echo back...
    /* make  a new generic php object (note:: php also supports objects - 
   but we are NOT doing that in this class - you can if you want ;)  )*/
    $myPackagedData=new stdClass();
    $myPackagedData->artist = $artist ;
    $myPackagedData->title = $title ;
    $myPackagedData->location = $loc ;
    $myPackagedData->description = $description ;
    $myPackagedData->creation_Date = $creationDate ;
    $myPackagedData->fileName = $fname ;
     /* Now we want to JSON encode these values as a JSON string ..
     to send them to $.ajax success  call back function... */
    $myJSONObj = json_encode($myPackagedData);
    echo $myJSONObj;

The code here is similar as before EXCEPT:
(1) Instead of echoing back HTML markup, we are packaging the data we want to send back into a generic PHP object.
(2) We encode this object as a JSON object and then echo this back to the page.
(3) The JQuery success function will be automatically triggered by the echo and receives the packaged JSON data…
Run. Almost there.

DISPLAY RESULTS USING JQUERY

The last part is to display the results to the page.
NOTE: the current data received is a JSON string . We want to convert it to a JavaScript object… So the following code does just that … add into the success function callback:

1
2
3
    //use the JSON .parse function to convert the JSON string into a Javascript object
     let parsedJSON = JSON.parse(response);
     console.log(parsedJSON);

Now if you run -> you will see that the response is a JavaScript object -> Yay..
As previously create a display function to use the data and create/append the necessary elements using JQuery:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
  // validate and process form here
    function displayResponse(theResult){
      let container = $('<div>').addClass("outer");
      let title = $('<h3>');
      $(title).text("Results from user");
      $(title).appendTo(container);
      let contentContainer = $('<div>').addClass("content");
      for (let property in theResult) {
        console.log(property);
        if(property ==="fileName"){
          let img = $("<img>");
          $(img).attr('src','images/'+theResult[property]);
 
          $(img).appendTo(contentContainer);
        }
        else{
          let para = $('<p>');
          $(para).text(property+"::" +theResult[property]);
            $(para).appendTo(contentContainer);
        }
 
      }
      $(contentContainer).appendTo(container);
      $(container).appendTo("#result");
    }

And finally call this function in your success callback AND use JQuery to reset the form fields …

1
2
3
displayResponse(parsedJSON);
  //reset the form
 $('#insertGallery')[0].reset();

RUN.
As mentioned before, PHP has quite a few inbuilt variables which are accessible within any scope (are known as Super Globals . If you would like more specific information follow the w3 schools link, or even better the php.net link.

GET and AJAX

As a last example/exercise lets take the example form from last week where we processed a form using GET – And let’s also try to process this form using AJAX …
LINK TO LAST WEEK’s PHP :
Recall – we have a form with three fields: we send the form to php – and then check if the favorite number is greater than 60 and depending on the outcome we output a particular message to the page ….
Now: instead of having the form being automatically processed and sent to PHP: we will allow JQUery and Ajax to do the processing.
This will then allow us to receive and output the response by the way of JQuery (java script) – and not having to reload the page… phew …

MODIFY HTML + FORM

1/ Remove the action and method attributes from the form.
2/ Give the form an id so that we can access easily with JQuery in a moment.
3/ Remove the php echo statement within the result div : (we will use JQuery to render the response)
4/ Give the result div an id (so that we can access later with JQUERY)
5/ Add in the jquery library (script tags)
6/ Add in empty script tags before closing body tags…
Ok: this is what your html should look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<html>
<head>
<title>INPUT to GET in php</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
 
</head>
<style>
p{
  padding:2px;
  width:100%;
}
p label{
  display:inline-block;
  width:10%;
  color:rgba(149, 0, 153,0.85);
 
}
.wrapper{
  width:75%;
  margin-left:12%;
}
h2{
  color:rgba(149, 0, 153,0.85);
 
}
input{
  width:50%;
}
input[type=submit]{
  width:8%;
}
form{
  padding:10px;
  background:rgba(149, 0, 153,0.25);
}
</style>
<body>
 
<div class = "wrapper">
  <h2> CART 351: PROCESS FORM WITH GET </h2>
<form id = "testGetAjax">
  <p><label>Fav Animal:</label><input type = "text" size="24" maxlength = "40"  name = "fav_animal" required></p>
  <p><label>Fav Color:</label><input type = "text" size="24" maxlength = "40"  name = "fav_color" required></p>
  <p><label>Fav Number:</label><input type = "number" size="24" maxlength = "40"  name = "fav_num" min="1" max="100" required></p>
  <p><input type = "submit" name = "submit" value = "send" id =buttonS /></p>
</form>
<div id = "resultDiv" style = "background:rgba(149, 0, 153,0.75);color:white"></div>
</div>
<script>
 
</script>
</body>
</html>

PROCESS FORM WITH JQUERY::

Just like we did in the previous example – we will use JQUERY to capture the submit event, and prepare the data to be sent to php.
Note: we are using a different JQUERY method to prepare & package the data: Add the following to your newly created script tags…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$(document).ready (function(){
    $("#testGetAjax").submit(function(event) {
        //stop submit the form, we will post it manually.
       //PREVENT THE DEFAULT behaviour ...
      event.preventDefault();
     console.log("button clicked");
     /* turn the form data into an array - as a set of url encoded key/value pairs */
    /* The jQuery serializedArray() Method is used to create a JavaScript array of objects by serializing form values*/
     let data =$('#testGetAjax').serializeArray();
     // Display the key/value pair OBJECTS using a foreach ...
     for(let pair of data.entries()) {
       console.log(pair); 
     }
    //request
 
 
   }) //submit
 });

OK – now run your page … so if you now try to submit the form – it gets caught by JQUERY and right now all we do is package the data and then output the key value pair objects – ok we are ready for AJAX …

AJAX + GET:

we will use the same $.ajax() as previously – but we can leave out certain properties – i.e. the GET as the method for sending is default … so adf the following into your submit event handler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$.ajax({
       url: "inputToGet.php",
       data: data,
       dataType: "text", /*response will be text */
       cache: false,
       timeout: 600000,
       success: function (response) {
       //reponse is a STRING (not a JavaScript object -> so we need to convert)
       console.log("we had success!");
       console.log(response);
      },
      error:function(){
     console.log("error occurred");
   }
 });

And then for testing purposes – REPLACE all your php at the top with the following:

1
2
3
4
5
6
7
8
9
10
<?php
//check if there has been something posted to the server to be processed
if($_SERVER['REQUEST_METHOD'] == 'GET')
{
  if($_GET['fav_color']){
  echo("we have data to process");
  exit;
 }
}
?>

Ok – if we run the page and submit the form you SHOULD have a hurrah moment … as we are successfully sending the data to the correct place …
Next: lets package and encode the data we want (the message from previous) and send the JSON string back to JQUERY …
Replace your inner if PHP statement with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if($_GET['fav_color']){
    $theMessage ="";
 
    $fcolor = $_GET['fav_color'];
    $fanimal = $_GET['fav_animal'];
    $fnum = $_GET['fav_num'];
    // output something with these values::
 
    if(intval($fnum>60)){
      $theMessage = "You chose a number greater than 60";
    }
    else
    {
        $theMessage = "You chose a number less than 60";
    }
 
   $myPackagedData=new stdClass();
   $myPackagedData->message = $theMessage ;
   echo json_encode($myPackagedData);
   //echo("we have data to process");
  exit;
 }

Now: when we run the page – we receive the message back as a response in our AJAX success callback handler – and now we can process and output:
Rewrite the success callback to be:

1
2
3
4
5
6
7
8
9
10
success: function (response) {
       //reponse is a STRING (not a JavaScript object -> so we need to convert)
       console.log("we had success!");
       console.log(response);
       let parsedJSON = JSON.parse(response);
       console.log(parsedJSON);
       displayMessage(parsedJSON);
       //reset the form
       $('#testGetAjax')[0].reset();
      }

And then we need to add in the displayMesage() function:

1
2
3
function displayMessage(messageObj){
  $("#resultDiv").text(messageObj.message);
}

Well – thats it! What I hope you can see from the second example is the COMMON methods used and that in actual fact – the data and input are different, the output is different – but the FUNDEMENTAL PROCESS for receiving and sending is the SAME…