De betekenis van Perl (Practical Extraction and Report Language) is een vrij goede beschrijving van wat deze scripttaal eigenlijk doet:

  • Extraction voor het kijken in bestanden en het “er uit trekken” van de voor jou belangrijke data;
  • Report voor het maken en rapporteren van de uitvoer (output), gebaseerd op de vereiste informatie, wat er was gevonden;
  • Het is een practische taal omdat het makkelijker is om dit soort scripts in Perl te schrijven dan in bijvoorbeeld C

Perl is in 1987 bedacht door Larry Wall, wie in die tijd al een bekende was in de UNIX software wereld (hij schreef de programma’s patch en rn (een usenet nieuwsreader)).

Perl is een scripttaal die bestaat uit stukjes van vele UNIX programma’s en programmeer-/scripttalen, onder andere sed, grep, awk, shell scripting en C. Perl is beschikbaar op vele operating systems, waaronder UNIX, Linux, Windows en Macintosh.

Perl is veel gebruikt in web-applicaties, met name de CGI-scripts zijn in Perl geschreven. Perl kan los gebruikt worden als script, maar ook als lijm tussen verschillende systemen. Perl bestanden eindigen op .pl of .cgi (CGI betekent Common Gateway Interface) en zijn z.g. “server side” scripts. Dit betekent dat de broncode van je Perlscripts “geïnterpreteerd” (geparsed) wordt door een parser en in je browser zie je daarom alleen de HTML-code.

Bij Vevida kun je standaard gebruikmaken van Perl-scripts, een cgi-bin directory is niet aanwezig. Deze kun je zelf aanmaken met je favoriete FTP-programma. Denk erom dat deze directory in de WWW-directory dient te staan. De geïnstalleerde versie is 5.12.2.

Wanneer de /cgi-bin folder schrijfrechten nodig heeft voor de te plaatsen scripts kun je deze rechten (schrijfrechten voor de IUSR) toekennen via MyVevida. Echter, normaliter zijn de IUSR-schrijfrechten niet nodig.

Het PATH naar de perl executable is c:/perl/bin. Standaard wordt de Perl ISAPI dll gebruikt. Dus dit stuk informatie is niet noodzakelijk voor scripts.

Heb je problemen met het gebruiken van Perl/CGI scripts dan kun je altijd om hulp vragen via het onderdeel Vragen op >MyVevida.
Vermeld hier wel extra informatie bij, zoals waar we je scripts kunnen vinden, welke foutmeldingen je krijgt, enz. Wij kunnen helaas niet garanderen dat wij je problemen kunnen oplossen. Probeer daarom eerst om je antwoord te vinden via internet.
Links naar sites over Perl/CGI kun je vinden op Perldoc.com.

Tip:
Zorg ervoor dat je jouw Perl bestanden met FTP in ASCII mode (plain/text) upload. Als je deze in BINARY mode upload, zal het script niet werken.

Tips en aanwijzingen

Regeleindes

In Perl worden regeleindes anders gedefinieerd dan in bijvoorbeeld ASP. Hier volgt een korte verklaring:

\n staat gelijk aan <LF> (LineFeed).
\r\n staat gelijk aan <CR><LF> (CarriageReturn LineFeed).

Optimaliseren print() calls

Het op het scherm printen van gegevens is een relatief zware, resource kostende, operatie. Bij vele print() statements (calls) kan het lang duren eer het script volledig geladen is. Elk Perl script dat veel print() calls heeft kan aanzienlijk in snelheid verbeterd worden door zoveel mogelijk data te verzamelen alvorens deze te printen. Perl maakt dit eenvoudig door de ‘.=’ operator (concatenation).
Bijvoorbeeld, de volgende code

$data = "Hello";
print $data;
$data = " world";
print $data;
$data = "\r\n";
print $data;

wordt herschreven naar:

$data = "Hello";
$data .= " world";
$data .= "\r\n";
print $data;

Of:

print "Hello world,
This is a multi
line print statement\r\n";

waardoor het script sneller laadt. Dit zelfde geldt voor overige, veel gebruikte calls.

Hello World

De volgende stukjes code printen een eenvoudig Hello World HTML pagina. Echter, op twee verschillende manieren. Functie georiënteerd:

#!C:/Perl/bin
use CGI qw/:standard/;                       # load standard CGI routines
print header,                                # create the HTTP header
start_html('hello world'),                   # start the HTML
h1('hello world'),                           # level 1 header
end_html;                                    # end the HTML

Of, object georiënteerd (OO):

#!C:/Perl/bin
use CGI;                                     # load CGI routines
$q = new CGI;                                # create new CGI object
print $q->header,                         # create the HTTP header
$q->start_html('hello world'),            # start the HTML
$q->h1('hello world'),                    # level 1 header
$q->end_html;                             # end the HTML

Het verschil is, wanneer er geen gebruik gemaakt wordt van de object georiënteerde manier, dat er een set functies geïmporteerd wordt naar onze name space (meestal de standaard functies). Er hoeft geen CGI object gecreëerd te worden.

Date

De functie date wordt niet ondersteund, in plaats daarvan kun je de volgende code gebruiken om de datum op te vragen:

my ($day, $mon, $year) = (localtime)[3, 4, 5];
$mon++; # 0-based index
$year = $year + 1900;
$date = sprintf ("%02i/%02i/%02i",$day, $mon, $year);

Indien je het tijdstip er ook bij wilt:

my ($day, $mon, $year, $hour, $min) = (localtime)[3, 4, 5, 2, 1];
$mon++; # 0-based index
$year = $year + 1900;
$date = sprintf ("%02i/%02i/%02i %02i:%02i", $day, $mon, $year, $hour, $min);

Sendmail

Op onze Windows webservers is sendmail onbekend. Hierdoor kun je hiervan geen gebruik maken. Een verwijzing in je (mail-)script naar /usr/lib/sendmail zal niet werken.

Een goede alternatieve mogelijkheid is het gebruiken van de Mail::SendMail module.

Documentatie over deze module vind je op http://theoryx5.uwinnipeg.ca/CPAN/data/Mail-Sendmail/Sendmail.html en http://alma.ch/perl/Mail-Sendmail-FAQ.html.

localhost is ook beschikbaar als mailserver.

Gegevens uit formulieren halen

Als je bijvoorbeeld een contactformulier heeft welke zijn gegevens naar een CGI mailscript verstuurd middels de POST methode, dan kun je deze gegevens in het CGI script verwerken met de functieparam(‘veld_naam’);.

Je dient dan wel “use CGI;” of “use CGI qw/:standard/;” in je script te gebruiken.

Voorbeeld:
contact.html:

<form method="post" action="/cgi-bin/mail.pl">
Uw naam: <input size="20">
Uw email: <input size="20">
Uw bericht: <textarea rows="10" cols="60">

mail.pl:

use CGI qw/:standard/;
$mail{Message} = "Naam: ". param('Name') . "\n";
$mail{Message} .= "Email: ". param('Email') . "\n";
$mail{Message} .= "Bericht: ". param('Message') . "\n";

Een ‘.’ (dot) is een concatenation of operator die verschillende strings aan elkaar koppelt.
Je zou bijvoorbeeld ook

$mail{Message} = "Naam: ". param('Name') . "Email: ". param('Email') . "\n\n";

in het script kunnen gebruiken.

Enkele voorbeeld- en environment variabelen

Omdat een backslash (\) ook in Perl/CGI commando’s wordt gebruikt, bijvoorbeeld bij de regeleindes, dien je deze te escapen als het geen commando is. Je doet dit door een extra te plaatsen (\\). C:\temp wordt dan C:\\temp of C:\/temp.

$PROGNAME="http://www.uwdomein.com/cgi-bin/script.cgi";
# $PROGNAME is de URL van dit script.

$BASEDIR="D:\\www\\uwdomein.com\\www\\cgi-bin\\";
# of
$BASEDIR="D:/www/uwdomein.com/www/cgi-bin";
# In $BASEDIR definieer je hier de directory waarin gegevens worden opgeslagen.

$SITEURL="http://www.uwdomein.com";
# Hier definieer je de URL van je site.

$SITENAME="De naam van uw site";
# Hier definieer je de naam van je site, m.a.w. de titel.

Let op: Dit zijn slechts voorbeelden, de daadwerkelijke definities kunnen per script verschillen!

Het volgende script print alle beschikbare Perl environment variabelen:

#!C:/Perl/bin
# 
# Print Perl environment variabelen
# (c)2006-2007 VEVIDA Services bv - Jan Reilink <info@vevida.com>
######

use CGI;
use CGI::Carp "fatalsToBrowser";
use strict;

my $query = new CGI;
my $running_under_perlis = $ENV{'PERLXS'};

if ($running_under_perlis ne 'PerlIS') {
  print $query->header;
}

print $query->start_html("Environment variabelen"),
$query->p($query->b("Environment variabelen")),
$query->start_table;

foreach my $key (keys(%ENV)) {
  print "<tr><td>$ENV{$key}:</td><td id="plain">$ENV{$key}</td></tr>\n"; 
}
print $query->end_table,
$query->end_html;

ActivePerl Documentation en Support

De ActivePerl Documentation en Support vind je op
http://aspn.activestate.com/ASPN/docs/ActivePerl/5.8/faq/ActivePerl-faq3.html
Voor Windows: http://aspn.activestate.com/ASPN/docs/ActivePerl/5.8/faq/Windows/ActivePerl-Winfaq8.html
Modules: http://aspn.activestate.com/ASPN/docs/ActivePerl/5.8/lib/ActivePerl.html

Het volgende script print alle geïnstalleerde Perl modules:

#!C:/Perl/bin
# 
# Print geïnstalleerde Perl modules
# (c)2006-2007 VEVIDA Services bv - Jan Reilink <info@vevida.com>
######

use CGI;
use CGI::Carp "fatalsToBrowser";
use ExtUtils::Installed;
use strict;

my $query = new CGI;
my $running_under_perlis = $ENV{'PERLXS'};

if ($running_under_perlis ne 'PerlIS') {
  print $query->header;
}

print $query->start_html("Perl modules"),
$query->p($query->b("Geinstalleerde Perl modules -- versies")),
$query->start_table;

my $instmod = ExtUtils::Installed->new();
foreach my $module ($instmod->modules()) {
  my $version = $instmod->version($module) || "???";
  print "<tr><td><a href="http://search.cpan.org/search?module=$module" target="_blank">
  $module</a></td>
  <td>--t</td>
  <td>$version</td>
  </tr>\n";
}
print $query->end_table,
$query->end_html;

Let op: Perl ISAPI vs CGI

Op de Vevida webservers kan Perl in twee modi gedraaid worden: als ISAPI filter (PerlIs) en in CGI mode.

Door Perl in te stellen als ISAPI functioneren scripts sneller, omdat niet voor iedere aanroep een apart proces gestart (en geheugen gereserveerd) hoeft te worden. Het is lastig de web server te laten crashen wanneer er van CGI mode gebruik gemaakt wordt (omdat er voor elke aanroep een apart proces gestart wordt), maar omdat de PerlIS DLL in het geheugen draait van de applicatie kan het voorkomen dat de Perl parser crasht vanwege programmeerfouten.

Extra zorg moet besteed worden bij het maken van PerlIS applicaties.

De meeste webservers staan ingesteld op PerlIs, een enkeling op CGI mode. Wanneer een webserver (of individuele website) ingesteld staat op PerlIs, dan is er een environment variabele PERLXS beschikbaar. Bij Perl in CGI mode ontbreekt deze. Deze environment variabele kan daarom als controlemiddel gebruikt worden:

my $running_under_perlis = $ENV{'PERLXS'};
if ($running_under_perlis ne 'PerlIS') {
  # de environment variabele PerlIs is niet beschikbaar, 
  # print de Content-type header
  print "Content-type: text/htmlnn;
  print "Perl in CGI-mode.\n";
}
else {
  print "Perl als ISAPI.\n";
}

Er zijn een aantal belangrijke verschillen tussen PerlIs en CGI, zoals al eerder genoemd draait PerlIs in het geheugen en wordt voor Perl CGI elke keer een nieuw proces gestart. Andere verschillen zijn onder andere de working directory. PerlIs draait vanuit de huidige directory waar het script staat: ./. Dit maakt het mogelijk om bestanden aan te roepen via use './library.pm';. Voor Perl als CGI geldt dit niet en moet het volledige PATH (pad) opgegeven worden: use 'D:/www/example.com/www/library.pm';.

Een ander belangrijk verschil is het printen van HTTP headers. Perl CGI verstuurt standaard geen Content-type header, deze moet specifiek in het script geprint worden. PerlIs verstuurt deze standaard wél. Wanneer deze ook nog in het script geprint wordt geeft dit foutmeldingen.

PerlIs (via de CGI class):

use CGI;
use CGI::Carp "fatalsToBrowser";
my $query = new CGI;
 
print $query->start_html("HTML heading"),
$query->p("some text in a P-alinea block"),
$query->blockquote(
  a({href=>"http://www.vevida.com"},"a link to VEVIDA.COM in a blockquote block")),
$query->end_html;

Perl CGI (via de CGI class):

use CGI;
use CGI::Carp "fatalsToBrowser";
my $query = new CGI;
 
print $query->header,                # print Content-Type header text/html
$query->start_html("HTML heading"),
$query->p("some text in a P-alinea block"),
$query->blockquote(
  a({href=>"http://www.vevida.com"},"a link to VEVIDA.COM in a blockquote block")),
$query->end_html;

Als Perl scripts in beide modi moet kunnen draaien, dan is het mogelijk om de environment variabele controle te gebruiken op bijvoorbeeld de volgende manier:

my $running_under_perlis = $ENV{'PERLXS'};
if ($running_under_perlis ne 'PerlIS') {
  print "Content-type: text/html\n\n;
  print "Hallo wereld!\n";
}
else {
  print "Hallo wereld!\n";
}

Of, via de CGI class:

use CGI;
use CGI::Carp "fatalsToBrowser";
my $query = new CGI;
my $running_under_perlis = $ENV{'PERLXS'};
if ($running_under_perlis ne 'PerlIS') {
  print $query->header;
}
print $query->start_html("HTML heading"),
$query->p("some text in an P-alinea block"),
$query->blockquote(
  a({href=>"http://www.vevida.com"},"a link to VEVIDA.COM in a blockquote block")),
$query->end_html;
exit();

Let wel: de CGI class staat los van Perl als ISAPI module of in CGI mode.

CGI

Wat vond je van dit antwoord?

Bedankt voor je feedback!

Er is een fout opgetreden. Probeer het later opnieuw.