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

Most revered monks,

I have the following cgi script, it can also be viewed in browsable form here.
What it does is simply compute the total price of the order.
#!/usr/bin/perl -w use CGI ':standard'; print header, start_html('Order Ice Cream with Price'), h1('Order Ice Cream with Price'); generate_form(); print_results() if param(); print end_html(); sub print_results { my @top = param('toppings'); print b('Customer name: '), param('customer'), br, "You ordered ", param('no_unit'), ' unit of ', param('cone'), ' cone.'; print br; # how to include the perl script "compute_price.pl" result here? print ('Total price is ...'); } sub generate_form { print hr, start_form, strong('Your name : '), textfield( -name => 'customer' ), br,br strong('Cone: '), radio_group( -name => 'cone', -multiple => 1, -values => [qw/sugar waffle/]),br,br strong('Number of Units: '), textfield( -name => 'no_unit'), br,br submit( -value => 'Send Order' ), end_form, hr; }
Now I have a perl script that does the computation. Typically it is executed in command line like this.
$ perl compute_price.pl -type sugar -unit 3
The perl script can be found below:
#!/usr/bin/perl -w use strict; use Data::Dumper; use Carp; use Getopt::Long; my $cone_type = 'sugar'; my $no_unit = 1; my $help = 0; if ( @ARGV == 0 ) { &usage(); exit(1); } my $res = GetOptions ( "type=s"=>\$cone_type, "unit=i"=>\$no_unit, "help"=>\$help,); if ($res) { die "Unit too large\n" if ($no_unit > 5); my %unitprice = ( 'sugar' => 100, 'waffle' => 200 ); my $total_price = $unitprice{$cone_type} * $no_unit; print "$total_price\n"; } sub usage { print <<HELP; Usage: perl $0 [-options] -h Print this help -type Cone type -unit No of Unit HELP exit; }
My questions are:
  1. How can I include "compute_price.pl" into the main cgi script above, so that it prints the total price?
  2. How can I also show the "die" version into the cgi-script when parameter given is incorrect. Just like in "compute_price.pl" ?

Regards,
Edward

Replies are listed 'Best First'.
Re: Howto include Perl Script into CGI script
by BerntB (Deacon) on May 17, 2006 at 09:17 UTC
    Sniff, sniff... the smell of ... homework? :-)

    Ah well, I'll give you some hints.

    You could make the second file into a module. (Read up on "package" and "use" it from your cgi file.) Implement it as a subroutine. You must put the previous shell-script (now module) in the Perl include path, as seen in the @INC array.

    To give an error message, check the return code of your new subroutine and show another html page.

    (You could also run the Perl script by using back-quotes, shell-script style.)

    Update: Added detail. Since the asking monk is much more experienced than me, I feel nervous about answering. But if he want to troll me more, I'll be happy to add more details. :-)

      (You could also run the Perl script by using back-quotes, shell-script style.)
      Hi BerntB,

      Thanks for your answer. Can you be a bit specific? Example?
      Here is what I have at the moment:
      sub print_results { my @top = param('toppings'); print b('Customer name: '), param('customer'), br, "You ordered ", param('no_unit'), ' unit of ', param('cone'), ' cone.'; print br; my $value = `perl compute_price.pl -type param('cone') -unit param +('no_unit')`; # Still doesn't show the value. What did I do wrong?? print 'Total price is', $value; }
      But it doesn't show the price as you try see from the link I have above. Is there anything I did wrong?
      It seem to me CGI script has different property with Perl script. Maybe backquote is not for it?

      Regards,
      Edward
        The "param('no_unit')" parts (inside the backquotes) are evaluated as shell script. Set them to variables and have the variables inside the "`".

        Update: Please note the dangers of "injecting" stuff like shell commands into your backquotes-eval if you use data that comes from the CGI! Use taint and/or the system() call with multiple parameters. (I.e. do system("perl", $param1, $param2);)

Re: Howto include Perl Script into CGI script
by blazar (Canon) on May 17, 2006 at 09:41 UTC
    How can I include "compute_price.pl" into the main cgi script above, so that it prints the total price?

    Usual answer: just make compute_price.pl into a module and use it from you cgi script, and possibly from a simplified cli version.

    How can I also show the "die" version into the cgi-script when parameter given is incorrect. Just like in "compute_price.pl" ?

    Just have a sub or method return, say, undef and have the main program display an error page if so.