Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
835 views
in Technique[技术] by (71.8m points)

A simple form application with Perl

I have an error while developing simple sign up form application with Perl.

This is my html.

<html>
<head>
    <meta charset="UTF-8">
    <title>Kay?t Formu</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
    <h2>Kay?t Formu</h2>
    <form id="signup-form" action="/sample_perl_application/signup.cgi" method="GET">
        <div class="form-group">
            <label for="name">Ad</label>
            <input class="form-control" id="name" name="name" type="text"/>
        </div>
        <div class="form-group">
            <label for="surname">Soyad</label>
            <input class="form-control" id="surname" name="surname" type="text"/>
        </div>
        <div class="form-group">
            <label for="age">Ya?</label>
            <input class="form-control" id="age" name="age" type="text"/>
        </div>
        <div class="form-group">
            <label for="sexual">Cinsiyet</label>
            <select class="form-control" id="sexual" name="sexual">
                <option id="male">Bay</option>
                <option id="female">Bayan</option>
            </select>
        </div>
        <input class="btn btn-default" id="save" name="save" type="submit" value="Kaydet"/>
    </form>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</html>

This is my perl script.

#!"c:xamppperlinperl.exe"

use strict;
use warnings;

use CGI;

local ($buffer, @pairs, $pair, $name, $value, %FORM);
# Read in text
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;

if ($ENV{'REQUEST_METHOD'} eq "GET") {
   $buffer = $ENV{'QUERY_STRING'};
}

# Split information into name/value pairs
@pairs = split(/&/, $buffer);

foreach $pair (@pairs) { 
   ($name, $value) = split(/=/, $pair);
   $value =~ tr/+/ /;
   $value =~ s/%(..)/pack("C", hex($1))/eg;
   $FORM{$name} = $value;
}

$name = $FORM{name};
$surname = $FORM{surname};
$age = $FORM{age};
$gender = $FORM{sexual};

print CGI::header();

print $name." ".$surname." ".$age." ".$gender;

I have an error like this. "End of script output before headers: signup.cgi". How can I fix the problem ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your first mistake is to try learning Perl from the TutorialsPoint site. They really have no idea what they are talking about. Try the Perl tutorials hub instead for pointers to better quality Perl tutorials.

Although CGI programs are designed to run on a web server, it's often useful to run them from a command line in order to debug them. In particular, when tracking down syntax errors, then you can use perl -c to see all of the problems. I put your code in a file called "testcgi" and ran the command perl -c testcgi. I got the following output:

$ perl -c testcgi 
Global symbol "$buffer" requires explicit package name (did you forget to declare "my $buffer"?) at testcgi line 8.
Global symbol "@pairs" requires explicit package name (did you forget to declare "my @pairs"?) at testcgi line 8.
Global symbol "$pair" requires explicit package name (did you forget to declare "my $pair"?) at testcgi line 8.
Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at testcgi line 8.
Global symbol "$value" requires explicit package name (did you forget to declare "my $value"?) at testcgi line 8.
Global symbol "%FORM" requires explicit package name (did you forget to declare "my %FORM"?) at testcgi line 8.
Global symbol "$buffer" requires explicit package name (did you forget to declare "my $buffer"?) at testcgi line 13.
Global symbol "@pairs" requires explicit package name (did you forget to declare "my @pairs"?) at testcgi line 17.
Global symbol "$buffer" requires explicit package name (did you forget to declare "my $buffer"?) at testcgi line 17.
Global symbol "$pair" requires explicit package name (did you forget to declare "my $pair"?) at testcgi line 19.
Global symbol "@pairs" requires explicit package name (did you forget to declare "my @pairs"?) at testcgi line 19.
Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at testcgi line 20.
Global symbol "$value" requires explicit package name (did you forget to declare "my $value"?) at testcgi line 20.
Global symbol "$pair" requires explicit package name (did you forget to declare "my $pair"?) at testcgi line 20.
Global symbol "$value" requires explicit package name (did you forget to declare "my $value"?) at testcgi line 21.
Global symbol "$value" requires explicit package name (did you forget to declare "my $value"?) at testcgi line 22.
Global symbol "%FORM" requires explicit package name (did you forget to declare "my %FORM"?) at testcgi line 23.
Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at testcgi line 23.
Global symbol "$value" requires explicit package name (did you forget to declare "my $value"?) at testcgi line 23.
Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at testcgi line 26.
Global symbol "%FORM" requires explicit package name (did you forget to declare "my %FORM"?) at testcgi line 26.
Global symbol "$surname" requires explicit package name (did you forget to declare "my $surname"?) at testcgi line 27.
Global symbol "%FORM" requires explicit package name (did you forget to declare "my %FORM"?) at testcgi line 27.
Global symbol "$age" requires explicit package name (did you forget to declare "my $age"?) at testcgi line 28.
Global symbol "%FORM" requires explicit package name (did you forget to declare "my %FORM"?) at testcgi line 28.
Global symbol "$gender" requires explicit package name (did you forget to declare "my $gender"?) at testcgi line 29.
Global symbol "%FORM" requires explicit package name (did you forget to declare "my %FORM"?) at testcgi line 29.
Global symbol "$name" requires explicit package name (did you forget to declare "my $name"?) at testcgi line 33.
Global symbol "$surname" requires explicit package name (did you forget to declare "my $surname"?) at testcgi line 33.
Global symbol "$age" requires explicit package name (did you forget to declare "my $age"?) at testcgi line 33.
Global symbol "$gender" requires explicit package name (did you forget to declare "my $gender"?) at testcgi line 33.
testcgi had compilation errors.

You can see that all of your errors are the same. You have forgotten to declare some of your variables. Your code should look like this:

#!"c:xamppperlinperl.exe"

use strict;
use warnings;

use CGI;

# Read in text
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;

my $buffer;

if ($ENV{'REQUEST_METHOD'} eq "GET") {
   $buffer = $ENV{'QUERY_STRING'};
}

# Split information into name/value pairs
my @pairs = split(/&/, $buffer);

my %FORM;
foreach my $pair (@pairs) {
   my ($name, $value) = split(/=/, $pair);
   $value =~ tr/+/ /;
   $value =~ s/%(..)/pack("C", hex($1))/eg;
   $FORM{$name} = $value;
}

my $name = $FORM{name};
my $surname = $FORM{surname};
my $age = $FORM{age};
my $gender = $FORM{sexual};

print CGI::header();

print $name." ".$surname." ".$age." ".$gender;

Notice that I have used my to declare the variables, not local. local is largely a hangover from Perl 4. Since Perl 5 was released over twenty years ago, my has been the best way to declare most variables in a Perl program. Notice, also, that I declare the variables as close as possible to where they are used.

There are some other things we can change here.

  • If we import named subroutines from CGI.pm, we can make the calls to them a little cleaner by omitting the package name.
  • We can use the param subroutine from CGI.pm to replace your buggy CGI parameter parser.
  • We can use the fact that Perl variables are expanded in double-quoted strings to make your print statement easier to read.

Making those changes, your code reduces to this:

#!"c:xamppperlinperl.exe"

use strict;
use warnings;

use CGI qw(param header);

my $name    = param('name');
my $surname = param('surname');
my $age     = param('age');
my $gender  = param('sexual');

# We're outputing plain text, not HTML
print header(-content_type => 'text/plain');

print "$name $surname $age $gender";

Doesn't that look simpler?

And you can test it from the command line:

$ perl testcgi2 'name=foo&surname=bar&age=18&sexual=M'
Content-Type: text/plain; charset=ISO-8859-1

foo bar 18 M

The biggest lesson here is that if you're learning a new language, you shouldn't trust random tutorial sites on the internet. They are rarely any use. Ask people who know the language where to find good resources.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...