Apache, make so it know
what to do with .pl files see pl file, make apache know what to do
with
arguments to a program - $ARGV[0], etc.
#!/usr/bin/perl -w
# check if we have 2 arguments:
die "USAGE: add number1 number2\n"
unless ($ARGV[1]);
print "$ARGV[0] + $ARGV[1] is:",
$ARGV[0] + $ARGV[1] ,"\n";
array, append to see push
array, clear - @array = ();
array,
compare two to see whether same or
not
foreach
(@a)
{
if ($a[$i] eq $b[$i]) {print " $a[$i]
is different from $b[$i] at $i."; last}
$i++;
}
array, length of
evaluate @array in scalar context such as @array + 1 or just refer to it as @array
scalar(@array)
$#array will return the subscript of the last element
of the array, or one less than the length, since there is (ordinarily) a 0th
element
array, loop through
for
my $var (@loop)
{
print
"$var in words is ${$a_2}[$var-1]\n";
}
array, move item in the middle
of a array to the front
best way:
@values = grep ($target, { $_ ne $default }
@values)
another way:
for (my $i = 0; $i
< @values; $i++)
{
if ($values[$i] eq $target)
{
splice (@values, $i, 1);
unshift (@values, $target);
last;
}
}
yet another way, in the
context of generating an HTML select list:
my $returnHTML =
popup_menu
(-name => $name, -values => \@values, -default => $default)
sample code for array manipulations
@final
= sort { $a->[0] cmp $b->[0]} @LoL;
for
$name (@final) {
print "$name->[0]
$name->[1]\n";
}
Notice that @final is getting copies of the
references to the data. After the call
to sort(), @final and @LoL will be two arrays pointing to the same data. Heres a better way that only takes one
step, without using an intermediary array:
foreach
my $thisAddrRef (sort {
$a->[-1] cmp
$b->[-1] or # zip
$a->[2] cmp
$b->[2] or # addressee
$a->[3] cmp $b->[3] or # addr1
$a->[4] cmp
$b->[4] or # addr2
$a->[5] cmp
$b->[5] # addr3
} @allAddr)
{
my @thisAddr = @$thisAddrRef;
}
array, pass several arrays as an argument to a
subroutine pass
the arrays as a reference. For example:
my
@arr1 = (1, 2, 3, 4);
my
@arr2 = ('One', 'Two', 'Three', 'Four');
&mysub(\@arr1,
\@arr2);
sub
mysub
{
my
($a_1, $a_2) = @_;
for
my $var (@{$a_1})
{
print
"$var in words is ${$a_2}[$var-1]\n";
}
}
Output:
=======
1
in words is One
2
in words is Two
3
in words is Three
4
in words is Four
array, pass and return several arrays pass and return the
arrays as a reference. For example:
#!/usr/bin/perl
-w
use
strict;
use
warnings;
#
Subroutine prototypes
sub
getAndReturnTwoArrays($$);
my
@array1 = ("a", "b", "c", "d");
my
@array2 = (1, 2, 3, 4);
#
Get two variables back
my
($one_ref, $two_ref) = getAndReturnTwoArrays(\@array1, \@array2);
my
@one = @$one_ref;
my
@two = @$two_ref;
print
"First: @one\n";
print
"Second: @two\n";
sub
getAndReturnTwoArrays($$)
{
($one_ref, $two_ref) = @_;
my @array1 = @$one_ref;
my @array2 = @$two_ref;
push (@array1, 'g');
push (@array2, 5);
return (\@array1, \@array2);
}
array, return several arrays as arguments from a
subroutine return
the arrays as a reference. For example:
If you can arrange for the function to receive
references as its parameters and return them as its return results, it's
cleaner code, although not so nice to look at. Here's a function that takes two
array references as arguments, returning the two array references ordered
according to how many elements they have in them:
($aref,
$bref) = func(\@c, \@d);
print
"@$aref has more than @$bref\n";
sub
func {
my ($cref, $dref) = @_;
if (@$cref > @$dref) {
return ($cref, $dref);
} else {
return ($dref, $cref);
}
}
#!/usr/bin/perl
use
strict;
use
warnings;
#
Subroutine prototypes
sub
get_two_arrays();
#
Get two variables back
my
(@one, @two) = get_two_arrays();
print
"First: @one\n";
print
"Second: @two\n";
sub
get_two_arrays() {
my @array1 = ("a",
"b", "c", "d");
my @array2 = (1, 2, 3, 4);
return (@array1, @array2);
}
array, slice see slice array
B
break out of a loop see loop, break out of
clear array see array, clear
code examples
command line, pass argument to a program from -
$ARGV[0], etc.
#!/usr/bin/perl -w
# check if we have 2 arguments:
die "USAGE: add number1 number2\n"
unless ($ARGV[1]);
print "$ARGV[0] + $ARGV[1] is:",
$ARGV[0] + $ARGV[1] ,"\n";
command line, run perl command from
>perl -e "print 'Hello world!';"
Hello world!
compare
two arrays to see whether same see array, compare two to see whether same
cookies
sub GetCookies{
$cookies = $ENV{'HTTP_COOKIE'};
@allcookies = split(/;\s*/,$cookies);
foreach $i (@allcookies){
($name,$value) = split(/\s*=\s*/,$i);
$cookie{$name}=$value;
}
}
date
of file see file time stamp
day
of year - (undef, undef, undef, undef, undef, undef, undef, $yday) =
localtime(time);
(from
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = localtime(time);)
debuggers,
interactive
ddd as in ddd --debugger 'perl d
frProjects'
ptkdb as in #!/usr/bin/perl d:ptkdb
decimal
format, force to 2 decimal places - $formatedX = sprintf ("%.2f\n",
$unformattedX);
delimiter
split
directory, read file names out of
#!/usr/bin/perl -w
my $dirName = '.';
opendir MAILDIR, $dirName or die "problem:
$!";
@allfiles = readdir MAILDIR;
closedir MAILDIR;
foreach $thisFileName (@allfiles)
{
next if
(($thisFileName eq '.') or ($thisFileName eq '..'));
my $thisFileNameWithPath
= $dirName . '/' . $thisFileName;
print
"name: $thisFileNameWithPath\n";
}
download perl.exe - ActivePerl
embed code in a string - @{[code]}
environment variables, print out all of:
sub PrintErr {
print
"<PRE>\nCGI Error: $!\n";
print
"Message: $_[0]\n\n";
print
"====== Form Variables ======\n";
foreach
$key (sort keys %in) {
print
"$key: \t$in{$key}\n";
}
print
"\n====== Environment Variables ======\n";
foreach
$env (sort keys %ENV) {
print
"$env: \t$ENV{$env}\n";
}
print
"\n</PRE>";
}
use by: &PrintErr;
escape
quotes (HTML) CGI::escapeHTML()
Excel
spreadsheet, write binary - Spreadsheet::WriteExcel
FAQ
file, redirect output to if perlprog is your
program, perlprog > output.txt
#!/usr/bin/perl
open (CRYPTSMP,
"encrypts.txt");
while ($record =
<CRYPTSMP>) {
print $record;
}
or
#!/usr/bin/perl
open (CRYPTSMP,
"encrypts.txt");
@raw_data=<CRYPTSMP>;
foreach $line (@raw_data)
{
($username,$seed,$encrypted,$linenum)=split(/\t/,$line);
print "username: $username\n";
#print "$line \n";
}
close(CRYPTSMP);
close(CRYPTSMP);
file time stamp use stat dont
use ctime if you want a raw string to sort on
#!/usr/bin/perl -w
use File::stat; # for mtime
use Time::localtime; # for ctime
my $dirName = '.';
opendir MAILDIR, $dirName or die "problem:
$!";
@allfiles = readdir MAILDIR;
closedir MAILDIR;
foreach $thisFileName (@allfiles)
{
next if
(($thisFileName eq '.') or ($thisFileName eq '..'));
my $thisFileNameWithPath
= $dirName . '/' . $thisFileName;
my
$date_string = ctime(stat($thisFileNameWithPath)->mtime);
print
"name & time stamp: $thisFileNameWithPath $date_string\n";
}
fill HTML template - see template, fill HTML
Hello
World see also pl
file, make apache know what to do with
#!/usr/bin/perl
print
"Content-type: text/html\n\n";
print
"<html>\n";
print
"<head>\n";
print
"<title>Hello world with Perl</title>\n";
print
"</head>\n";
print
"<body>\n";
print
"<h1>Hello world with Perl</h1>\n";
print
"<p>Howdy, world!</p>\n";
print
"</body>\n";
print
"</html>\n";
here-document, Use of uninitialized value in
concatenation (.) or string look for uninitialized variables in the body
Host of incoming web user - see IP
address, translate to host
HTML
quotes, putting into without confusing HTML CGI::escapeHTML()
HTML template, fill - see template, fill HTML
information - see environment variables, print out all of
IP address of incoming web user
$ENV{'REMOTE_ADDR'}
$remote_address
= $ENV{'REMOTE_ADDR'};
@subnet_numbers
= split (/\./,$remote_address);
$packed_address
= pack ("C4",@subnet_numbers);
($remote_host)
= gethostbyaddr ($packed_address, 2);
say you have array of
hashes:
$field
[0] {name} = "addressID";
$field
[1] {name} = "name";
$field
[2] {name} = "addr1";
$field
[3] {name} = "addr2";
to join,
my
$selectClause = join ', ', map {$_->{name}}@field;
join, opposite of split - $string = join ', ', @list;
K
evaluate @array in scalar context such
as @array
+ 1
or just refer to it as @array
scalar(@array)
$#array will return the subscript
of the last element of the array, or one less than the length, since there is
(ordinarily) a 0th element
length of string - $lengthStr
= length ($string);
lists
see arrays
loop, break
out of
next skip to end of
current loop iteration, start next iteration
last skip to end block, as
if condition had returned false
M
modulus if (5 % 2 == 1) {}
newsgroups
output, redirect to file
if perlprog is your program, perlprog > output.txt
P
page that
called this script - $ENV{HTTP_REFERER}
parse a
variable that has several lines, each
line with variable = value, into a hash
use
strict;
use
as;
use
Data::Dumper;
use
vars qw (
%myTestHash
);
sub
buildHash ($$);
%myTestHash
= ();
frInit
('joe_support@artselect.com', 'no CGI');
my
$tmp =<<"EOF";
something
else
var1
=> 'value1'
var2
=> 'value2'
var3
=> 'value3'
EOF
print
$tmp;
my
$regExpToParseVarAndValue = '^([^\=]+?)\=> \'([^\']+?)\'$';
$tmp
=~ s/$regExpToParseVarAndValue/buildHash ($1, $2)/gme;
frExit
(0);
sub
buildHash ($$)
{
my ($varName, $varValue) = @_;
print
"---------------------------------------------------------\n";
print "varName = $varName\n";
print "varValue = $varValue\n";
$myTestHash{$varName} = $varValue;
}
path from the command line, type:perl -e 'print join "\n", @INC'
pl file, make apache know what to do with
make sure apache-perl is
installed
e /etc/apache/httpd.conf
(or e /etc/apache2/sites-available/default)
C-s Exec-CGI
Change
# Options Indexes Includes FollowSymLinks
MultiViews
to
Options All MultiViews
In the same file, for
each <VirtualHost>:
ScriptAlias /cgi-bin/
/var/www/apache2-default/mysite.com/cgi-bin/
<Directory "/home/mysite.com cgi-bin">
AllowOverride None
Options ExecCGI All +MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
AddHandler cgi-script cgi pl
</Directory>
Or whatever other paths
in which you want Apache to look for your scripts
e mime.types
/etc/init.d/apache
restart
perl
/var/www/HelloWorld.pl
chown www-data
HelloWorld.pl
position in a string pos Returns the offset of where
the last m//g search left off for the variable is in question ($_ is used when
the variable is not specified).
while ($string =~ m/regex/g) {
print "Found '$&'. Next
attempt at character " . pos($string)+1 . "\n";
}
process id - $$
program arguments - $ARGV[0], etc.
#!/usr/bin/perl -w
# check if we have 2 arguments:
die "USAGE: add number1 number2\n"
unless ($ARGV[1]);
print "$ARGV[0] + $ARGV[1] is:",
$ARGV[0] + $ARGV[1] ,"\n";
program that's running right now - see script that's running
right now
to
simply append a 1-dimensional array (or scalar) to the end of another
1-dimensional array - push
@originalArray, @appendedArray
to push a 1-dimensional
array to a 2-dimensional list of 1-dimensional arrays:
#!/usr/bin/perl
my @input = ( [1, 2, 3], [4, 5,
6] );
#my @input = ( \@line1, \@line2
);
my @data;
my $i = 0;
# The 'my' in the loop is
imperative, otherwise, each row will erase the
# previous one.
# The braces in @{ ... } are imperative because of operator
precedence
# against the [ ] brackets
while (my @dataRow =
@{$input[$i++]}) {
print @dataRow, "\n";
# This stores a pointer to the @dataRow array, i.e. its address
or
# reference.
# So essentially, you get an array of addresses of arrays,
which
# effectively gives you an array of arrays. Note that each sub-array
# (each row) can be
different sizes unlike traditional 2-dimensional
# arrays.
push @data, \@dataRow;
}
# Now how do we get the data out?
# So in our array of arrays, if
you say @data[5] you're saying
# data[5] which you want to be an
array. but that's not the way we
# stored things; we stored things
as addresses of (or references to) arrays.
# So you have to say $data[5] to
get the address of the array, and use @ to
# get the array, i.e. @{$data[5]}
This is called dereferencing.
print "Output loop\n";
foreach (@data) {
print @{$_}, "\n";
# I could have this instead, but less clear:
#print @$_, "\n";
print ${$_}[0], "\n";
# I could have this instead, but less clear:
#print $$_[0], "\n";
}
# Or equivalently
print "Explicit
Output\n";
print @{$data[0]},
"\n";
print ${$data[0]}[0],
"\n";
print @{$data[1]},
"\n";
print ${$data[1]}[0],
"\n";
push, opposite of unshift (prepends instead of
tacking onto the end)
Q
quotes, putting into HTML without confusing
HTML CGI::escapeHTML()
R
read file see file, read
real number, check for
/^-?\d+\.?\d*$/ does not like leading 0
/^-?\d*(\.\d+)?$/ better
redirect output to file
if perlprog is your program, perlprog > output.txt
regular expressions
see
parse a variable that has several lines, each line with variable
= value, into a hash
require problems (from google
posting)
the "compile once, run multiple times" pitfall (indicated by "works about 1 out of every two tries). Try this:
- run your httpd with the -X switch (daemon won't fork)
- replace "require '/home/httpd/html/stdinc.pl';" with
use lib '/home/httpd/html/';
require 'stdinc.pl'
run
perl command from command line
>perl -e "print 'Hello world!';"
Hello world!
S
script
that's running right now -
$ENV{SCRIPT_NAME}
scope
session management
Apache-Session
or here
for list of all modules in mod_perl (Apache/Perl)
non-sequential
# initialize @array with 10 elements,
# with values 1 through 10
@array = (1..10) ;
# @NewArray is a subset of @array
# (Note that @array is preceded by '@' here.
# We have to do that, since we're accessing
# several array elements at once.)
@NewArray = @array[3,6,9] ;
# Now, let's print the result
print join(" ", @NewArray) ;
OUTPUT:
4 7 10
sequential
# initialize @array with 10 elements,
# with values 1 through 10
@array = (1..10) ;
@AnotherNewArray = @array[3..6] ;
print join(" ", @AnotherNewArray) ;
OUTPUT:
4 5 6 7
from the end instead of
from the beginning
# initialize @array with 10 elements,
# with values 1 through 10
@array = (1..10) ;
# print the last element in the array
print $array[-1] ;
OUTPUT:
10
sort array of arrays
see array or arrays, sort
split, opposite of
join
subroutine
sub mysubroutine
{
print "Not a very interesting routine\n";
print "This does the same thing every time\n";
}
regardless of any parameters that
we may want to pass to it. All of the following will work to call this
subroutine. Notice that a subroutine is called with an &
character in front of the name:
&mysubroutine; # Call the subroutine
&mysubroutine($_); # Call it with a parameter
&mysubroutine(1+2, $_); # Call it with two parameters
sub printfirsttwo
{
print "Your first argument was $_[0]\n";
print "and $_[1] was your second\n";
}
substring - $portion = substr($string, start number,
length);
syntax
type in "perldoc [command]" as in "perldoc perl"
perldoc perlsyn - perl
syntax
perldoc perlsub - perl
subroutines
perldoc perlfunc - perl built-in
functions -- ALL the functions - very tedious but seems to be complete
tab - \t
timestamp
use POSIX;
my $datestamp = strftime("%r
%m/%d/%Y", localtime);
or
timestamp of existing file see file time stamp
time
#!/usr/bin/perl -w
my $now = time();
($sec, $min, $hour, $mday, $Month, $year,
$wday, $yday, $isdst) = localtime ($now);
print "seconds = $sec\n";
print "Minutes after each hour (0 - 59)
= $min\n";
print "Hour since
print "Numeric day of the month (1 - 31)
= $mday\n";
#print "Number of months since January
(0 - 11) = $Month\n";
# increment the month by 1 to get real month
my $RealMonth = $Month + 1; # Months of the
year are not zero-based
print "Real Month = $RealMonth\n";
#print "year (Number of years since
1900) = $year\n";
# adding 1900 will create a four digit year
value in your Perl script
$yyyy = $year + 1900;
print "year = $yyyy\n";
print "weekday (Number of days since
Sunday (0 - 6)) = $wday\n";
print "Number of days since January 1 (0
- 365) = $yday\n";
print "A flag for daylight savings time
= $isdst\n";
Tutorials
web page that called this
script - see page that
called this script
while loop,
break out of see loop, break out of