The point of Server-Side Scripts is to use input from the User to create a page. One way to do so is to pass it as a **parameter** through the URL with a question mark after your script filename, like so;
`https://coding.ndcfinearts.ca/cgi-bin/firstperl.cgi?Windsor`
Your script needs to receive that **parameter**. It does so through what is known as a Global Hash, meaning that it already exists on the server, so you do not need to instantiate (create) it.
The `%ENV` (usually referred to as the Environment Hash) will hold the information the User has sent to you in the `QUERY_STRING` key. You call it with `$ENV{'QUERY_STRING'}`. Consider the link above, and how `firstperl.cgi` could use the information as below;
```perl
$myInput = $ENV{'QUERY_STRING'};
print "Mr. $myInput is a super geek.";
```
>CHALLENGE: Try creating a script that accepts an input from the user as a **parameter**, and prints something to the screen from that input. One idea is to create a script that accepts a user's name, and provides them with a "Welcome" message.
# Accepting Multiple Parameters
What if one **parameter** isn't enough? What if you need the user to send lots of information about different things? The ampersand `&` is how they would send you a **list** of data.
`https://coding.ndcfinearts.ca/cgi-bin/lots.cgi?Windsor&Joel&Mr.`
However, if you simply call `$myInput = $ENV{'QUERY_STRING'}`, it won't know which data is which. So you need to connect the **list** of data the user sends in a **list** of your own.
First, we need to split the data we get into a list that PERL will understand. There are a number of pieces of information worth noting in the following *function* ...
`split(/\&/,$ENV{'QUERY_STRING'});`
The `split` function takes a scalar variable (in this case, the data that came from the URL parameter) and turns it into a PERL **list** where the ampersand (which was escaped) separated the different items in the list.
But now we need to assign those items to scalar variables we can work with. Here's one way;
`($firstParameter,$secondParameter,$thirdParameter) = split(/\&/,$ENV{'QUERY_STRING'});`
Now all those URL parameters are in variables we can work with. **But** what if we don't know how many parameters the user might decide to send us? They could send us megabytes worth of parameters! Let's make a PERL **Array**.
`@allParameters = split(/\&/,$ENV{'QUERY_STRING'};`
> **Lists** in PERL are also called **Arrays**, and are represented by the `@` instead of the `
Now all we need is a **loop** function to help us read everything inside the list ...
```perl
@allParameters = split(/\&/,$ENV{'QUERY_STRING'});
for (@allParameters) { # loops through every item in the list
print "$_<br>\n";
}
```
As you can see, we use the `$_` system variable which represents the current item in the **list** as we go through the **list**.
We can also make our own variable instead of using the system variable, like so ...
```perl
@allParameters = split(/\&/,$ENV{'QUERY_STRING'});
for $thisItem (@allParameters) {
print "$thisItem<br>\n";
}
```
Both of these scripts will have the same effect, producing an output that will look like an HTML file with the following inside it;
```html
Windsor<br>
Joel<br>
Mr.<br>
```
> CHALLENGE: Create a script that will receive lots of user **parameters** and print them to the screen.
# Sorting the Data
Our challenge now comes with the issue of detecting what order the user put the parameters in. If we keep the code we wrote above, but the user enters the values in different orders, we'll get different results.
`https://coding.ndcfinearts.ca/cgi-bin/lots.cgi?Windsor&Joel&Mr.`
will produce
```html
Windsor<br>
Joel<br>
Mr.<br>
```
`https://coding.ndcfinearts.ca/cgi-bin/lots.cgi?Mr.&Joel&Windsor`
will produce
```html
Mr.<br>
Joel<br>
Windsor<br>
```
That won't do if we need the data in a specific way. To solve this, we **key** the data into a **hash**. We'll only use 2 keys in this example.
`https://coding.ndcfinearts.ca/cgi-bin/keyed.cgi?first=Joel&last=Windsor`
In this example, the user created a **key** called `first` with a **value** of `Joel` and a **key** called `last` with a **value** called `Windsor`. Now, how do we put that data into PERL so we can work with it? The same way we did before, with one extra step.
The `$ENV{'QUERY_STRING'}` will be `"first=Joel&last=Windsor"`. We must first get all the parameters into a **list**.
```perl
@allParameters = split(/\&/,$ENV{'QUERY_STRING'});
```
Now `@allParameters` has the following items in its list ...
```
first=Joel
last=Windsor
```
If we ever wanted a specific item in an **array**, we treat the list like a **scalar** and indicate the **index** (position) of the item in the **array** with `[]` square brackets. For example, the `first=Joel` is in the top, or zero-position of the **array**, so we could call `$allParameters[0]` which will give us the top item in the **array.** An example of that is below.
```perl
print "$allParameters[0] is the first item, $allParameters[1] is the second item";
```
This would output ...
`first=Joel is the first item, last=Windsor is the second item`
Now we create a **hash**. A **hash** is like an **array** except that all the items in a **hash** have a name. Hashes are created with `%`.
```perl
%USERDATA = ();
for (@allParameters) { # loop through each item in the list
($key,$value) = split(/\=/,$_); # split each item by the =
$USERDATA{$key} = $value;
}
```
Just like with **arrays**, if we want to call on only one item in the **hash**, we use the `
at the front of it, but this time we don't use the `[index]`, we instead use `{}` curly brackets to give that particular item a keyed name.
In the example above, on the first time in the loop we named a new item in the `%USERDATA` **hash** `first`, and gave it a value of `Joel`. When the code looped around again onto the second item in `@allParameters`, we made another new item in the **hash** and named it `last`, giving it a value of `Windsor`. The resulting information in `%USERDATA` is as follows;
```
$USERDATA{'first'} is "Joel"
$USERDATA{'last'} is "Windsor"
```
It doesn't matter what order the user typed in the parameters, we will still put the right value with the right key. The code above will still give us the exact same information, even if the user typed this into the URL ...
`https://coding.ndcfinearts.ca/cgi-bin/keyed.cgi?last=Windsor&first=Joel`
Now we can report exactly what the information we gathered was, again with a loop.
```perl
for (keys %USERDATA) { # loop through each item in the hash
print "$_ is $USERDATA{$_}<br>\n";
}
```
This time we aren't looping through a **list**, but through all the key-names of every item in the **hash**. Therefore as we loop through, the `$_` standard variable represents the current name of the item in the **hash**. When we called `$USERDATA{$_}`, we asked for the value of the item in the **hash** with the name represented by `$_`. The output of the code would be ...
```
first is Joel<br>
last is Windsor<br>
```
> CHALLENGE: Create a script that collects keyed **parameters** and prints them in order to the screen.