470 likes | 740 Views
Perl, CGI and DBI. Ashley George ageorge@cs.dal.ca March 7th, 2005. Overview. Each of the following will be presented with explanations and brief exercises: Perl usage, syntax, semantics, subroutines CGI and Apache DBI and Oracle. Perl In Brief. Using the Perl Interpreter A Perl Program
E N D
Perl, CGI and DBI Ashley George ageorge@cs.dal.ca March 7th, 2005
Overview • Each of the following will be presented with explanations and brief exercises: • Perl usage, syntax, semantics, subroutines • CGI and Apache • DBI and Oracle
Perl In Brief • Using the Perl Interpreter • A Perl Program • Elements of Perl • Syntax, Data Structures, Subroutines and Refs • Perl Library and Builtin Functions • perldoc, perl manpages
Tutorial Files • All the programs seen in this tutorial are available on the web http://www.cs.dal.ca/~ageorge/4173/ • and in the following directory on torch /users/grad/ageorge/4173/ • Three subdirectories containing perl scripts: • "perllang", "CGI", "DBI"
Log into Torch… $ mkdir ~/4173tutorial $ cd 4173tutorial $ cp ~ageorge/4173tut.tar.gz . $ gtar zxvf 4173tut.tar.gz $ cd perllang; ls (and see: ) helloworld.pl insertsort.pl … • (use more/less/pico/vim/emacs to view/edit!)
Using the Perl Interpreter • The interpreter is invoked from the command line on torch.cs.dal.ca. • Use the syntax perl -w filename where filename is the name of a text file containing your Perl program. • (Typically filename.pl orfilename.cgi )
A Very Short Perl Program print("Hello world!\n"); http://www.cs.dal.ca/~ageorge/4173/perllang/helloworld.pl
A Slightly Longer Perl Program @nums = (5, 2, 7, 4, 8, 9); for ($j = 1; $j < @nums; $j++) { $key = $nums[$j]; $i = $j - 1; while($i >= 0 && $nums[$i] > $key) { $nums[$i+1] = $nums[$i]; $i = $i - 1; } $nums[$i+1] = $key; } print("@nums\n"); http://www.cs.dal.ca/~ageorge/4173/perllang/insertsort.pl
Almost the Same, But Different @list = (5, 2, 7, 4, 8, 9); @sorted = shift(@list); for (@list) { $i = 0; while ( $i < @sorted && $sorted[$i] < $_ ) { $i++; } splice(@sorted, $i, 0, $_); } print("@sorted\n"); http://www.cs.dal.ca/~ageorge/4173/perllang/insertsort2.pl
What are those things? • Scalar variables (scalar: storing a single value) $identifier $arrayidentifier[$index] $assocarrayidentifier{$key} • Arrays and Associative Arrays @arrayidentifier @arrayidentifier[$slice0, $slice1,…$sliceN] %assocarrayidentifier
How do I use 'em? • Declare arrays: @array = ($scalar1, $scalar2, $scalar3, … $scalarN); • Access array elements: $array[$index] = $scalarvalue; • Declare associative arrays: %hash = (key1, val1, key2, val2, key3, val3); • Access associative array elements: $hash{$key} = $scalarvalue;
How do I use 'em? (cont'd) • There are many operators • +, -, /, *, &&, ||, ==, !=, <, > • Many of those are familiar to you.. • also see perlop man page • eq, lt, gt, ne, ?:, ., x, ** • You can also pass scalar variables, arrays and associative arrays into subroutines.
Literals and Scalar Variables $i = "abcdefg"; # strings $j = 0.78; # real numbers $k = 255; # decimal integers $l = 0377; # octal integers $m = 0x00ff; # hexadecimal integers $n = 2.55E+2; # also # interpreted quotes! print("$i $j $k $l $m $n\n"); $o = $l + $m; print("$o\n"); http://www.cs.dal.ca/~ageorge/4173/perllang/variables.pl
Arrays and Array Elements @names = ("Zhiyong", "Jamie", 52, "Ashley", "Helmut"); # if you have @array, use $array[$index] print("$names[2]\n\n"); # prints "52\n\n" # sort them lexically @sortednames = sort(@names); # for each element in sorted names, print... for $element (@sortednames) { print("$element\n"); } http://www.cs.dal.ca/~ageorge/4173/perllang/lists.pl
Associative Arrays %employees = ( "Bob" => 7.50, "Martin" => 8.50, "Stevie" => 6.75 ); # Cost for Bob and Martin per hour print( $employees{"Bob"} + $employees{"Martin"} . "\n"); # prints "16\n" @names = keys(%employees); print("@names\n"); http://www.cs.dal.ca/~ageorge/4173/perllang/associativearrays.pl
Control flow statements • for, while, if/elsif/else, until, unless, etc… see perlsyn for details. (man perlsyn or see the webpage…) • Note that blocks are required -- you cannot omit braces { } anywhere.
Control Flow (cont'd) • An interesting feature: for (@array) { # now $_ has each element ... } • At each iteration of the loop, $_ will contain the next item in the array.
Subroutines • Syntax: sub identifier { statements… } • Usage (for the above subroutine): identifier()
Subroutines and Parameters • At the beginning of any subroutine, a special array called @_ ("at underscore") contains all the parameters passed to a subroutine. • Example on following slide • subroutine declarations can follow code which invokes them.
Subroutines sortandprintnames("Zhiyong", "Ashley", "Jamie", "Helmut"); print(factorial(5) . "\n"); # prints 120 sub sortandprintnames { for (sort(@_)){ print("$_\n"); } } sub factorial { my $n = shift(@_); # get one parameter if ($n == 0) { return 1; } return $n * factorial($n-1); } http://www.cs.dal.ca/~ageorge/4173/perllang/subroutines.pl
Naming Your Parameters • You can assign @_ to an array of named scalars: sub namedparams { my ($p1, $p2, $p3) = @_; etc etc etc } • Of course, use whatever names you please.
Returning • You can also return scalars, arrays and associative arrays from a subroutine. return $value; return @list; return %hash;
References • What about … • passing more than one data structure? • returning more than one data structure? • You might initially try sub myroutine { my (@array1, %array2) = @_; … # doesn't work. }
References (cont'd) • You can take a reference to any data structure by prefixing it with a backslash ("\") (ie, $ref = \@array; ) • You can dereference a reference by prefixing it with the appropriate symbol: $, @ or %. • (ie, @array = @$ref; )
Incorrect attempt @names = ("Zhiyong", "Jamie", 52, "Ashley", "Helmut"); %classes = ( "4173" => "Thursday", "3171" => "Tuesday", "1101" => "Friday" ); printstuff(@names, %classes); # no good.. sub printstuff { my (@names2, %classes2) = @_; print("@names2\n"); my @keys = keys(%classes2); print("@keys\n"); # empty! } http://www.cs.dal.ca/~ageorge/4173/perllang/subproblems.pl
Fixed with References. @names =("Zhiyong", "Jamie", 52, "Ashley", "Helmut"); %classes = ( "4173" => "Thursday", "3171" => "Tuesday", "1101" => "Friday" ); printstuff(\@names, \%classes); sub printstuff { my ($names2, $classes2) = @_; print("@$names2\n"); my @keys = keys(%$classes2); print("@keys\n"); } http://www.cs.dal.ca/~ageorge/4173/perllang/subproblemsfixed.pl
Library Functions • Perl has many builtin functions that are useful for manipulating scalars and arrays. • The next few slides list some of the commonly used functions… you can look them up as necessary using perldoc -f functionname • Or, you can look at • http://www.perl.com/doc/manual/html/
Scalar String Functions chomp: remove a newline from a string lc (uc): get the lowercase (uppercase) version of a string length: get the length of a string substr: get substrings of a string split: split a string into substrings ("tokens")
Useful Array Functions • pop: removes and returns last value • push: adds a new last value • shift: removes and returns first value • unshift: adds a new first value • splice: inserts (and possibly overwrites) a list of elements into an array • sort: mutable sort function - flexible!
I/O Functions • open, close open FILE, "file.txt"; • read, write (low-level I/O) • Use the < > operator to read lines. while (<FILE>) { # now $_ contains the next line # (might want to chomp, split…) … }
Review Exercise • Merge two sorted arrays • Write a subroutine that takes two sorted arrays as its parameters by reference. • Merge the two arrays, maintaining sorted order and return the result. • Try using push, shift in a loop. • You can append arrays like this: @newarray = (@array1, @array2);
Merging Two Sorted Arrays sub merge { my ($ref1, $ref2) = @_; my @ar1 = @$ref1; my @ar2 = @$ref2; my @ar3 = (); while ( @ar1 > 0 && @ar2 > 0 ) { if ($ar1[0] <= $ar2[0]) { push @ar3, shift @ar1; } elsif ($ar1[0] > $ar2[0]) { push @ar3, shift @ar2; } } @ar3 = (@ar3, @ar1); @ar3 = (@ar3, @ar2); return @ar3; } http://www.cs.dal.ca/~ageorge/4173/perllang/merge.pl
CGI, Perl, Apache • CGI: Common Gateway Interface • A standard interface for programs running on a webserver to receive data from a user. • Specifies a set of environment variables • A CGI program retrieves these values, parses them and acts on the input, typically a set of key-value pairs.
Preparing cgi-bin on Torch $ cd ~/public_html $ mkdir cgi-bin $ chmod a+rwx,og-rw cgi-bin
Using Perl with CGI • In order to use Perl scripts with CGI, you must place the script in ~/public_html/cgi-bin • Note that: • At the top of your perl script, the very first line MUST be: #!/usr/bin/perl -w • Your script must be called filename.cgi • also, do chmod u+x filename.cgi
Invoking your CGI Program • If you called your Perl script test.cgi • You would run it by entering into a web browser the following URL (with your username) http://www.cs.dal.ca/~username/cgi-bin/test.cgi • The web server on torch will process your script and report failure or print your script's output.
More CGI Caveats • Any calls to Perl's print function will be printed to the user's browser. • Furthermore, you must call print "Content-type: text/html\n\n"; before you make any other calls to print.
CGI Exercise • Can you make a simple CGI script that prints Hello world! in the user's browser? • Remember to place the script in ~/public_html/cgi-bin. • It should be named filename.cgi • chmod u+x filename.cgi
Hello World! #!/usr/bin/perl print "Content-type: text/html\n\n"; print "Hello world!\n";
Printing Here Docs • Sometimes you want to print something fairly long… like an HTML document. • You can use Here docs for this purpose. print << EOF this is a lot of text that will be printed out blah blah blah… text… lots of it. even more text.. EOF
Here Docs • One neat thing about here docs is using them to print out HTML incorporating Perl variables. • Just as in a regular print statement, Perl variables can be embedded in here docs.
Example #!/usr/bin/perl $sum = 2 + 2; print <<EOF Content-type: text/html <html> <head><title>The value of 2 and 2...</title></head> <body><p>The value of 2 + 2 is: $sum</p></body> </html> EOF
CGI Input • So now you could • generate web pages dynamically • perform any calculation or operation • But how do you handle user input? • You need to parse CGI variables. • These are passed to you in environment variables accessible through %ENV. • It's a nuisance.
CGI.pm • A feature-filled Perl module that handles the details of CGI for you. • Parses CGI environment variables • Handles POST and GET methods of HTML form submission • More...
An HTML Form <html> <head><title>Name Collection</title> </head> <body> <form method="GET" action="http://www.cs.dal.ca/~ageorge/cgi-bin/test.cgi"> <p>What is your name?</p> <p><input name="name" size="30"></p> <input type=submit> </form> </body> </html> http://www.cs.dal.ca/~ageorge/4173/CGI/input.html
A Script Processing That Form's Input #!/opt/bin/perl use CGI qw(:standard); print "Content-type: text/html\n\n"; print "Hello world!\n"; $name = param('name'); print "Your name is $name\n";