Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

New and need help in cgi, perl

by britney (Acolyte)
on Feb 04, 2002 at 20:30 UTC ( [id://143293]=perlquestion: print w/replies, xml ) Need Help??

britney has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I am new to Perl, just learn this code in Essential Web Perl5 when i summit it it will write to 1.html, 2.html or number+.html but i would like to have it write to title.html so i can look it easier ex. Title 020212 file will save as 020212.html Thanks for your help
#!/usr/bin/perl5/perl &get_form_data; print "Content-type: text/html\n\n"; opendir(DIR, "./Data"); while($name = readdir(DIR)) { next if $name !~ /^\d*.html/; push(@files, $name); } close(DIR); if($#files == 0) { $nextfile = "1.html"; } else { $lastfile = $files[$#files]; $lastfile =~ s/.html//g; $nextfile = $lastfile + 1; $nextfile .= ".html"; } open(OUT, ">Data/$nextfile"); print OUT "<HTML>\n<HEAD>\n "; print OUT "<TITLE>\n"; print OUT "$FORM{'title'}\n"; print OUT "</TITLE>\n"; print OUT "</HEAD>\n"; print OUT "<BODY BGCOLOR=\"#FFFFFF\">\n"; print OUT "<CENTER><H1>\n"; print OUT "$FORM{'heading'}\n"; print OUT "</H1></CENTER><BR>\n"; print OUT "<P>\n"; print OUT "$FORM{'body'}\n"; close(OUT); push(@files, $nextfile); print "<HTML>\n<BODY>\n"; foreach $file (@files) { print "<A HREF=\"Data/$file\">$file</A>\n"; print "<BR>\n"; } print "</BODY>\n</HTML>\n"; exit; sub get_form_data { # Get the input read(STDIN, $buffer, $ENV{ 'CONTENT_LENGTH' } ); # Split the name-value pairs @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); # Un-Webify plus signs and %-encoding $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/\0//g; $value =~ s/<!--(.|\n)*-->//g; $value =~s/\cM//g; $value =~s/\n\n/<p>/g; $value =~s/\n/<br>/g; $FORM{ $name } = $value; } }

Replies are listed 'Best First'.
Re: New and need help in cgi, perl
by cjf (Parson) on Feb 05, 2002 at 00:20 UTC
    As Ryszard said, CGI.pm is great at producing HTML, but more importantly it will reliably parse the name-value pairs sent by your form. To see how easily many parsers fall apart, read this, then take comfort in the fact that CGI.pm has been extensively tested by many people and is very good at what it does.

    You should also consider using strict, taint mode, and warnings. They'll save you a lot of trouble down the road. For more information on them, consult super search :)

Re: New and need help in cgi, perl
by Ryszard (Priest) on Feb 05, 2002 at 00:11 UTC
    For starters I would recommen you check out CGI.pm on CPAN. its just briliant for producing HTML.

    After that it all you need is a deterministic method of generating your filename. Check out localtime if youre interested in dates. If youre reading and writing files, make sure you spit out the last used filesequence somewhere (a config file perhaps). When it comes to generating the next file, you read in your config file, (last file counter) increment it, then apply it.

Re: New and need help in cgi, perl
by CharlesClarkson (Curate) on Feb 05, 2002 at 07:10 UTC

    Hi all, I am new to Perl, just learn this code in Essential Web Perl5

    Please throw this book away. It is teaching you Bad Things™. Pick one of these Perl Books instead.

    when i submit it it will write to 1.html, 2.html or number+.html. But i would like to have it write to title.html so i can look it easier. (ex. Title 020212 file will save as 020212.html.)

    If you do this you will lose whatever is already in 020212.html. Is there some other name you would like to use instead?

    Let's take a closer look at what you presented:

    #!/usr/bin/perl5/perl

    In modern perl a beginner would most likely start with:

    #!/usr/bin/perl5/perl -T use strict; use warnings; use diagnostics;

    And if your using a perl version prior to 5.6.0:

    #!/usr/bin/perl5/perl -wT use strict; use diagnostics;

    Take a look at Use strict and warnings for some excellent reasons.

    &get_form_data;

    When you write your own subroutine for retreiving form data it is often referred to as rolling your own or re-inventing the wheel. Many much more experienced programmers have tweaked most of the errors out of common tasks. These programmers often place their experience into modules.

    Modules are available for perl on CPAN. We can avoid the most common mistakes by re-using this code instead of rolling our own. For CGI applications, you'd do best with CGI.pm:

    use CGI qw/:standard center/;
    print "Content-type: text/html\n\n";

    We'll skip this for how, but you should know that it's sending headers to the browser by printing them. The browser is waiting for us to print something.

    opendir(DIR, "./Data"); while($name = readdir(DIR)) { next if $name !~ /^\d*.html/; push(@files, $name); } close(DIR);

    Personally, I prefer indentation to create order and improve readability:

    opendir(DIR, "./Data"); while( $name = readdir(DIR) ) { next if $name !~ /^\d*.html/; push(@files, $name); } close(DIR);

    Unfornately this will not work because we enforced strict in the beginning of the program. There are also a few other glaring mistakes which is why I encouraged you to rid yourself of the book you were reading.

    When we open a file or dir it is a Good Thing™ to check for success.

    opendir (DIR, "./Data") || die "Couldn't open directory ./Data: $!"; OR: opendir DIR, "./Data" or die "Couldn't open directory ./Data: $!";

    I prefer the second one as I don't like the extra parenthesis. This is a question of style and you might have a look at perlsyn for style suggestions.

    When we use strict we enforce certain rules about variable use. One rule is that we may have to use my the first time we use a variable. It also means we have to pay attention to what scope we first <tt class='inlinecode'>my</tt> it in.

    while( $name = readdir(DIR) ) { next if $name !~ /^\d*.html/; push(@files, $name); }

    Might be re-written as:

    my @files while( my $name = readdir DIR ) { next if $name !~ /^\d*.html/; push(@files, $name); }

    When you become more experienced, you might shorten it to:

    my @files while( readdir DIR ) { push @files, $_ if /^\d*.html/; }

    When we close a file or dir it is a Good Thing™ to check for success just as we did with opendir above. Here we use closedir

    closedir(DIR) || die "Couldn't close directory './Data': $!"; OR: closedir DIR or die "Couldn't close directory './Data': $!";

    The following if-else block determines the value of $nextfile which is the name of the file to be written to. According to your message, you would like this to be named the same as the last file in the directory. That would write over whatever is already there, so let's just name it "testing.html". Look in the directory to make certain we're not overwriting some other file named "testing.html".

    my $next_file = 'testing.html';

    Because we accessed CGI.pm with Use CGI qw/:standard center/; we are prepared to use its function oriented mode and can re-write the next section. Note: I am not using flock, but you should read up on it when you can.

    open OUT, ">Data/$nextfile" or die "Cannot open 'Data/$nextfile': $!"; print OUT start_html( -title => param('title'), -bgcolor => '#FFFFFF'), center( h1( param('heading') ) ), br, p( param('body') ), end_html; close OUT or die "Cannot close 'Data/$nextfile': $!";;

    Actually, we should have put a check in there for the existence of param('title') , param('heading'), and param('body'). Our new code will fail if they don't all exist.

    The rest of the script, properly indented, looks like:

    push(@files, $nextfile); print "<HTML>\n<BODY>\n"; foreach $file (@files) { print "<A HREF=\"Data/$file\">$file</A>\n"; print "<BR>\n"; } print "</BODY>\n</HTML>\n"; exit;

    And might be re-written as:

    push @files, $nextfile; print headers, start_html( -title => 'File Listing'); print a({ -href => "Data/$_" }, $_ ), br for @files; print end_html; exit;

    Let's look at it all together:

    #!/usr/bin/perl5/perl -T use strict; use warnings; use diagnostics; use CGI qw/:standard center/; opendir DIR, "./Data" or die "Couldn't open directory ./Data: $!"; my @files; while ( my $name = readdir DIR ) { next if $name !~ /^\d*.html/; push(@files, $name); } closedir DIR or die "Couldn't close directory './Data': $!"; my $next_file = 'testing.html'; open OUT, ">Data/$next_file" or die "Cannot open 'Data/$next_file': $! +"; print OUT start_html( -title => param('title'), -bgcolor => '#FFFFFF'), center( h1( param('heading') ) ), br, p( param('body') ), end_html; close OUT or die "Cannot close 'Data/$next_file': $!"; push @files, $next_file; print header, start_html( -title => 'File Listing'); print a({ -href => "Data/$_" }, $_ ), br for @files; print end_html;



    HTH,
    Charles K. Clarkson
    Clarkson Energy Homes, Inc.
      Hi Charles, My system have perl 5.001, and somehow when i run your code i get error.
      webhome: 19% write.cgi Global symbol "name" requires explicit package name at write.cgi line +10. Global symbol "name" requires explicit package name at write.cgi line +11. No comma allowed after filehandle at write.cgi line 28.
      Here are the code i used:
      #!/usr/bin/perl -T use strict; # use warnings; # use diagnostics; use CGI qw/:standard center/; opendir DIR, "./Data" or die "Couldn't open directory ./Data: + $!"; my @files; while ( my $name = readdir DIR ) { next if $name !~ /^\d*.html/; push(@files, $name); } closedir DIR or die "Couldn't close directory './Data': $!"; my $next_file = 'testing.html'; open OUT, ">Data/$next_file" or die "Cannot open 'Data/$next_ +file': $!"; print OUT start_html( -title => param('title'), -bgcolor => '#FFFFFF'), center( h1( param('heading') ) ), br, p( param('body') ), end_html; close OUT or die "Cannot close 'Data/$next_file': $!"; push @files, $next_file; print header, start_html( -title => 'File Listing'); print a({ -href => "Data/$_" }, $_ ), br for @files; print end_html; exit;

        Hi Charles, My system have perl 5.001, and somehow when i run your code i get error.

        My best recommendation would be to upgrade to a more modern perl. I have my domain name on a server that refuses to upgade past 5.003, though, so I understand that may not be possible for you. I am sure they will understand when I move my domain next month.

        Unfortunately, I have never programmed in perl below 5.003, so I can only guess what is happening. You might try posting your question again as a new question. Title it as "Need to run this in perl 5.001" or something. There should be some others who are familiar with that version. You may as well explain in your message why it is not possible to upgrade your perl version. If you can get the version number of CGI.pm installed on your system, people will find that helpful too.

        In an effort to save face, perhaps I can help with the CGI.pm version info. In the CGI version I have this works:

        use CGI 'version'; print version;

        I'm sorry. It never occurred to me to find out which perl version you were using. I was recently admonished by crazyinsomniac for doing something similar.




        HTH more,
        Charles K. Clarkson
        Clarkson Energy Homes, Inc.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://143293]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-03-29 04:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found