Home

HTML basics

Web Safe Colors

Symbols

Java Tutorial

XML Tutorial

C++ Tutorial

Perl Tutorial

View Guestbook

Sign Guestbook

Links

 

Learn Perl now!
You can learn Perl now. The language isn't as hard as people are saying. I will show you how to begin your Perl programming career, by showing you some examples, and by letting you see how the language works. I suggest you download a version of Perl for use under DOS/Windows (ActivePerl), if you run your script with it you can see if the script has errors...so you don't have to be online all the time. You can download it for free somewhere on this page. You can edit your scripts using a normal text editor, for example notepad.

This tutorial is written for Perl 5, some things will not work in older versions!

Getting started
The first line of your program should always be something like #!/usr/bin/perl. This may differ if your version of Perl is located somewhere else. You must always remember that Perl is CaSe SeNsItIvE, which means that Perl is not thesame as PERL or perl. The variables in your script are also case-sensitive, and depending on your server, the filenames can be case-sensitive too.
All the other lines starting with # (the 'shebang') are comments, like QBasic has REM and '. However, this first line of your script is read by the system to know which program to call to execute the script.

Now, your first script should be very easy...let's create a 'hello, world!' example. This script should look like this (select the text and press CTRL+C to copy it into memory, then go to your text editor and press CTRL+V to paste):
#!/usr/bin/perl
print "Hello, world!\n";

Now save the file as hello.cgi and try to run it from the DOS Perl that you just downloaded by typing 'perl hello.cgi'...you will see a text "Hello, world!" there!
From this first small script you can already learn some things: the print command prints something to the screen (or browser, if it is an online script). \n breaks the line, so the next line that will be printed will appear on a new line. You always put a ; after commands.

Now, we make an online 'Hello, world' script, that displays in your browser. To do this, you will first need to tell the language that it is sending a HTML file to the browser...do this by typing print "Content-type:text/html\n\n"; (exactly like that, with 2 \n's). Now save the script again, and start your FTP client to log in to your homepage. Set it to send as ASCII and upload your hello.cgi. Next, CHMOD it 755. This changes the file permissions so you can run the program. You will have to do this every time you create a new script, if you're re-editing an existing script, the permissions will remain the same and won't need to be changed again.
CHMOD 755 makes the file readable, writable, and executable (RWX) for the owner(you), readable and executable for GROUP and OTHER. This means visitors to your site can run the script.
Now, when that is finished, open your browser and go to the cgi file by typing in the full address. If everything's right, you will see the text 'Hello, world!' in your browser window. If not, you must have done something wrong. Maybe you uploaded your CGI file to another directory than the cgi-bin and your server can't run CGI files from there? It sometimes happens...
If it did work, we can continue.
To display a small webpage instead of just a simple text is just easy. The following code will work:
#!/usr/bin/perl
print "Content-type:text/html\n\n";
print "<html><title>Hello, world!</title>\n";
print "<body>\n";
print "<h2>Hello, world!</h2>\n";
print "</body></html>\n";
That's all that's needed...no additional tags. If you want, you can try it and upload the file again, just follow the same steps as above.Ofcourse, this can be done a lot 'cleaner' by removing the multiple print commands. The following code does thesame thing as the above code:
print "Content-type:text/html\n\n";
print "<html><title>Hello, world!</title>\n
<body>\n
<h2>Hello, world!</h2>\n
</body></html>\n";


Because the print command uses those ""'s, you will get problems if you have any HTML code that includes them. But no worries, there is something to fix that and it is very easy: Just put a \ before it, like this:
print "<A HREF=\"http://www.qb45.com\">\n";
That will make it work!
Probably the cleanest way is like this:
print qq~<A HREF="http://www.qb45.com">\n~;
Now you don't have to worry about any quotes anymore =)

Variables
What is a programming language without variables? Well not much more than some useless trash I think. Ofcourse Perl also uses variables. So here's an explanation on how to use them!
Small note: There are programming languages that do not use variables. That is what they call 'functional programming'. Haskell is an example of that. In functional programming there are no variables, everything is calculated using functions.

Scalar variables are used to store one value. There are called like $variable, so $whatever, $x, $y etc. will all work. Here's how you give them values:
$one = 1;
$name = "Jorden";
$pi = 3.141592;

You can now see that, different from other programming languages, the scalar ($) variable can hold both numbers AND text. Also, you don't need a declaration of your variables, just add a line like this and it will work!
Perl variables can also change from numbers to text or the other way. Like this:
$age = 17;
$age = "Seventeen ($age).";

Internally Perl can store it as a double, int, float, long, or char.

You can also use arrays. A scalar variable can only store one value, an array can hold multiple. The array variable looks like @arrayname. Some example code:
@names = ("Jorden","Rob","Fred");
print "$names[0]\n";
print "$names[1]\n";
print "$names[2]\n";
Ofcourse, there are other ways to do this, easier ways. Just create some sort of FOR...NEXT loop like in QB, like this:
@names = ("Jorden","Rob","Fred");
foreach $a (@names) {
print "$a\n";
}

I can see that you are already starting to understand more and more of the language...great isn't it?
Some more array-specific functions:
@names = ("Jorden","Rob","Fred");
$lastname = pop(@names); # returns "Fred", the last value of the array.
$firstname = shift(@names); # returns "Jorden", the first value of the array.

sort(@names) # sorts the values of @names alphabetically
reverse(@names) # inverts the @names array
$#colors # the length of the @names array
join(", ",@names) # joins @names into a single string, separated by the expression ", " (you can change that)
To add some code to an array:
push(@names,"Pete"); # adds "Pete" to the end of the @names array

@names2 = ("Name1","Name2","Name3");
push(@names,@names2); #appends the values in @names2 to the end of @names.

Note: Sort and reverse will not work on their own. You can use them like this:
foreach $a (sort @names) { print "$a\n";}

There is another type of variables , hashes (%). Hashes also are arrays.

Because you probably are using a DOS Perl version, you can't get input from the browser, for example by filling in a form. To test functions offline, just use something like this:
#!/usr/bin/perl
$homepagetitle = "Perl programming tutorial";
print "Hello my friend. What is your name?\n";
$you = <STDIN>;
chomp($you);
print "Hi $you. Welcome to $homepagetitle.\n";

(Since $you also contains the carriage return itself, we use chomp($you); to remove that)

Environment variables
Environment variables are variables of the current session. They are stored in a hash called %ENV/$ENV.

Here are some useful environment-variables:
Variable Name Info
HTTP_COOKIE The visitor's cookie, if one is set
HTTP_REFERER The URL of the page that is calling your script. This points to the HTML file that contains your FORM-code.
HTTP_USER_AGENT The browser type of the visitor
QUERY_STRING The query string
REMOTE_ADDR The IP address of the visitor
REMOTE_USER The visitor's username (for .htaccess-protected pages)
REQUEST_METHOD GET or POST
SCRIPT_FILENAME The full pathname of the current CGI
SERVER_NAME Your server's domain name
There are more, and some servers use other variables as well...But I don't feel the need to mention those here!
You can use the environment variables in your scripts like this:
print "You asked for file $ENV{'HTTP_FILENAME'}\n";

Reading data from forms
You need to create a .html file for this example, because here we start using forms...Copy this text into your .html file:
<form action="env.cgi" method="POST">
Enter your name here: <input type="text" name="name" size=30>
</form>

Now save this file, call it env.htm and upload this file to your page. Open it in your browser window.
If you would run this code, it will pass the data to the CGI file like this: name=Firstname+Lastname.
You can also send multiple values like this:
<form action="env.cgi" method="POST">
First Name: <input type="text" name="fname" size=30><p>
Last Name: <input type="text" name="lname" size=30><p>
</form>

This will be passed to the env.cgi script like this::$ENV{'QUERY_STRING'} = fname=Jorden&lname=Chamid
(separated by &)
This is unusable in most cases, so you will need to decode it. We use the split function for this. The following code is very much used, I advise you to use it in your own programs too if you will ever need it!
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}

Now, we have $FORM{'fname'} which contains the first name, and $FORM{'lname'} with the last name, filled in on the form. Isn't that much better?
The following code is a very much used program for mailing the results of a form to you...Have a look, and try to understand the code! (it shouldn't be hard, since it has many comments in it!)
#!/usr/bin/perl

print "Content-type:text/html\n\n";

#This code is used often, you might want to save this to use in your own programs! It retrieves all the info from a FORM.
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}

$Change this to the path of your mailing program on your homepage!
$mailprog = '/usr/sbin/sendmail';

# change this to your own email address. Because we used single quotes('), we can remove the \ before the @!!! With double quotes, you still need one.
$recipient = 'yourname@domain.com';

open (MAIL, "|$mailprog -t") or &errorhappened("Can't access $mailprog!\n");

print MAIL "To: $recipient\n";

print MAIL "Reply-to: $FORM{'email'} ($FORM{'name'})\n";

print MAIL "Subject: Form Data\n\n";

#Print all the variables to the mail program:
foreach $key (keys(%FORM)) {
print MAIL "$key = $FORM{$key}\n";
}

#If you're done with mailing, be sure to close the mailprog!
close(MAIL);

# now print something to the HTML page, usually thanking the person
# for filling out the form, and giving them a link back to your homepage
print
<h2>Thank You</h2>
Thank you for writing. Your mail has been delivered.<p>
Return to our <a href="index.html">home page</a>.
</body></html>
EndHTML
;

sub errorhappened {
($errmsg) = @_;
print "<h2>Error</h2>\n";
print "$errmsg<p>\n";
print "</body></html>>\n";
exit;
}

Save it as mail.cgi and upload it as you did before. Don't forget to CHMOD

You can now test the script with the following code:
<form action="mail.cgi" method="POST">
Your Name: <input type="text" name="name">
Email Address: <input type="text" name="email">
Age: <input type="text" name="age">
Favorite Color: <input type="text" name="favorite_color">
<input type="submit" value="Send">
<input type="reset" value="Clear Form">
</form>

You also can see that this script uses a SUB, like QBasic has them too. A sub here is created by typing
sub Subname {
then comes the code, and end it with }. You can now call that sub with &Subname. You can put subs anywhere in the program, as long as it doesn't change the other code.
If you want the email to be send to more than one email address, just do it like this:
$recipient = 'yourname1@domain.com, yourname2@domain.com'; etc.

IF ... THEN (Conditions)
Congratulations, you've just learned how to get data mailed to you! But what if the user didn't fill out all forms that are required?
After the data has been mailed to you, you can't let him change it anymore.
So, let's learn how to check variables!

The first thing you will need to know, is how to check whether a field is filled in. We're gonna use the data from the previous chapter to do that! It can be done in different ways, I'm gonna show you some of them;
# We want to check if an email address was filled in
if ($FORM{'email'} eq '') {
&fatal_error ("Please fill in the email field!");
}

#Put the routines that mail it to you here!

sub fatal_error {
local($e) = @_;
print "<html>\n";
print "<title>Fatal Error</title>\n";
print "<font face=Arial SIZE=2>\n";
print "<h2>Fatal Error</h2>\n";
print "<b>$e</b><p>\n\n";
print "If this error continues, you should contact the admistrator.\n</html>";
exit;
}

Now this was one way to do it. We could have also done it like this:
unless ($FORM{'email'}) {
&fatal_error ("Please fill in the email field!");
}

You might also want to check if the user submitted a 'legal' email address, by checking for a @ in the field. Try this:
unless ("$FORM{'email'}" =~ "@") {
&fatal_error ("Your email address does not contain a @. Please change it!");
}

In the first example of this chapter, we used "eq" to check for two variables to be the same. We could have also used "==". See the table below for the other conditions!

Test

Numbers

Strings

$x is equal to $y

$x == $y

$x eq $y

$x is not equal to $y

$x != $y

$x ne $y

$x is greater than $y

$x > $y

$x gt $y

$x is greater than or equal to $y

$x >= $y

$x ge $y

$x is less than $y

$x < $y

$x lt $y

$x is less than or equal to $y

$x <= $y

$x le $y

This will sure help your scripting :)

Some more examples, so you can get to understand better (not related to the example):
if ($firstname eq "Jorden") {
print "Hello Webmaster\n";
}
elsif ($firstname eq "Sander") {
print "Hello brother of the webmaster!\n";
}
else {
print "Hello, I think we haven't met yet!\n";
}

Some additional checks, that will save some space when scripting:
if ($FORM{'name'} eq "" or $FORM{'email'} eq "" or $FORM{'message'} eq "") {
&fatal_error("Please fill out the fields for your name, email, and message!");
}
For () statement

The For () statement is sort of similar to the IF statement. However, it works in a loop, unlike IF.
There are 3 arguements in a For () statement. The syntax:

for ($var = 0; $var < $number; $var++) {

}

The first arguement, $var = 0, tells the loop what value to start its variable with.
The second arguement, $var < $number, tells the loop to continue while the main variable ($var) is less than $number.
The third arguement, $var++, tells the loop to add 1 to the variable, aslo known as the incriment. For example:

for ($i = 0; $i < 5; $i++) {
print "$i\n";
}

Would display:

0
1
2
3
4

You can also use different incriments instead of $i++ such as $i--, $i = $i + 20, etc.

The Foreach statement is similar to the FOR statement. Except this time it's used for arrays. Before I told you about arrays, and I sort of explained the foreach statement, but not fully.
There are 2 arguements in a Foreach () statement, 1 is optional. The syntax:

foreach $variable (@array) {

}

$variable is the variable that contains each value of the array. Everytime the foreach loop cycles, $variable contains the next "line" of data in the array.
@array is the array that foreach cycles through. On each cycle, foreach gives the next line of @array to $variable. For example:

@names = ("Terry", "Midge", "TTWBDesign", "DustyCor");
foreach $name (@names) {
print "$name\n";
}

Would display:

Terry
Midge
TTWBDesign
DustyCor

The variable (not array) however is optional. For instance, you can do this:

@names = ("Terry", "Midge", "TTWBDesign", "DustyCor");
foreach (@names) {
$people++;
}

Split is another function that I mentioned in the last section. It splits one variable into several other one.
The syntax:

($var1, $var2, $var3, etc.) = split(/$sep/,$variable);

What that does is splits $variable into $var1, $var2, and $var3 by $sep which is the separator. For example:

$sentence = "This is a test."; ($var1, $var2, $var3, $var4) = split(/ /,$sentence);

The results will leave $var1 containing "This", $var2 containing "is", $var3 containing "a", and $var4 containing "test.". $sentence was split into 4 variables, each divided by a single space which was identified by / /.


Reading & Saving from & to files
If you get data emailed to you, your mailbox might get full if a lot of people do that. Also, other people aren't able to read it. For Discussion boards, Guestbooks, etc., it might be more useful to save it to a file on your server. Luckily, this is also possible, and is just as easy as getting your server to send out mail! You just need to CHMOD the file to 777 first.
Now just look at the example below:
open(HANDLE,"filename");
You use the "HANDLE" to point to the file. After you open it, you can print data to it like this:
print HANDLE "data you want to add";
The above example will not work though...We opened the file for reading only! To open a file for (over)writing, use this:
open(OVERWRITE,">filename");
To add data to the end of the file, we need to open for append:
open(APPEND,">>filename");
Please note that I changed the name of the handle...it's a good idea to do that, so you won't end up trying to write to a READ-only file!
Sometimes servers can act really strange, so I advise you to use the full path to your files when opening them...for example:
open (READ, "/home/www/yourname/filename.txt");
If it didn't work, nothing will actually happen...the user will not get a notice of the failing script. So use the following code:
open(READ,"filename.txt") or &fatal_error("Can't open file for reading.");

Well, now to actually do the writing, you can write it like this:
print APPEND "$FORM{'name'}\n";
print APPEND "This is the end of the file\n";
print APPEND "$emailaddress\n";

Well that shouldn't be too hard to figure out. A hint:$value =~ s/\n/ /g;
This removes all carriage returns from $value, for if you want to save data on one line (you will also have to remove \n from the code above when writing the data to a file). To make multiple variable one line, you must use the join function. Like this:
$addline = join ("|","$FORM{'url'}","$FORM{'email'}");
Ofcourse there are other ways to do it. Like this:
$addline = "$FORM{'url'}|$FORM{'email'}";
Just see which one you like best.

Example of how you could read all the data from a file (if you can understand this, you can basically do all the writing you want!):
Reading files goes like this:
@input = <READ>;
This inmediately reads the entire file into the array variable @input. You can now use the code above on arrays to read specific parts of it. If you only want to read one line:
$input = <READ>;
The following example shows you how to print an entire data-file to the screen:
open(READ,"readdata.txt") or &fatal_error("Can't open file for reading!");
@array = <READ>;
close(READ);

foreach $line (@array) {
chomp($line);
print "$line\n";
}

When you're done reading/writing to a file, you should better close the file, like this:
close(filehandle);
Small note #1: Try to teach yourself to use UPPERCASE handles for writing to files. If you, for example, use open(log,"filename.html");, you will call the log() function, which returns the natural logarithm of $_. Using uppercase avoids all this.
Small note #2: In Perl 5, the & in &fatalerror above is optional.

 

Congrats...You now know Perl CGI Scripting.