Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Calling a sub-routine in CGI

by Anonymous Monk
on Aug 09, 2002 at 02:47 UTC ( [id://188807]=perlquestion: print w/replies, xml ) Need Help??

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

Hello fellow monks, I'm learning CGI, and have a questions (Probably an easy one). I have a cgi script, and wish to call a subroutine via 'a href', what is the correct syntax? I am trying this code, but unfortunately it doesn't work!
print "<a href=\&toggle_on>ON</a>";
&toggle_on is my sub-routine Thanks guys (and gals)

Replies are listed 'Best First'.
Re: Calling a sub-routine in CGI
by DamnDirtyApe (Curate) on Aug 09, 2002 at 03:10 UTC

    I think you're blurring the line between HTML and Perl more than is possible here. As I understand it, an HTML anchor is simply a way of requesting a certain page from the web browser. It's not directly a way of executing code. What you may be able to do instead is something like:

    print qq[<a href="my_script.pl?sub=toggle_on">ON</a>] ;
    Then, have my_script.pl test the value of param( 'sub' ), and execute the appropriate subroutine.

    If you choose to do something like this, take precautions against malicious posts, and do not execute user input directly.


    _______________
    DamnDirtyApe
    Those who know that they are profound strive for clarity. Those who
    would like to seem profound to the crowd strive for obscurity.
                --Friedrich Nietzsche
Re: Calling a sub-routine in CGI
by fuzzyping (Chaplain) on Aug 09, 2002 at 04:58 UTC
    As DamnDirtyApe has started to allude to, you cannot use a hyperlink to call a subroutine. A perl subroutine is encapsulated within the CGI process. An HTML hyperlink is simply another way of requesting a web "object", where an object can be any manner of hosted files... text/html, images, cgi scripts, etc. However, the execution of said scripts does NOT happen within Apache's process... a separate perl process is started to handle the cgi task; only the output of the script is returned to Apache for output to the requestor (browser).

    Assuming you want the script to perform some function as defined by a subroutine, I suggest you create a URL with custom or hidden parameters, which, when read in by the cgi, understands to run the appropriate subroutine. Example:
    #/usr/bin/perl -w use strict; use CGI qw(:standard); my $cgi = CGI->new; if ($cgi->param()) { if ($cgi->param('toggle_on')) { &toggle_on; } elsif ($cgi->param('toggle_off')) { &toggle_off; } else { &default; } } else { # print form print $cgi->a({href => "/cgi-bin/script.cgi?toggle_on=1"}, "Toggle + On"); # print more stuff }
    Hope this helps!

    -fp
Re: Calling a sub-routine in CGI
by Massyn (Hermit) on Aug 09, 2002 at 05:53 UTC

    Hi Anonymous Monk,

    Hmmm... Yes, it easy, depending on what you want to do. Are you

    a) Trying to execute what ever is in &toggle_on and put the output of that text in your A HREF command, or are you

    b) Trying to get &toggle_on to execute when you click the ON hyperlink? It almost looks like this is what you're trying to do. If so, you're going the wrong way.

    Solution A

    print "<a href=" . &toggle_on . ">ON</a>";

    Solution B

    #get the UNWEB procedure in here $FORM=&unweb; if($FORM{action} eq "toggleon") { &toggle_on; } else { print "<a href=\"?action=toggleon\">ON</a>\n"; }
    This is a very simplified way of going.
      I'm sorry, but I'm still learning...Where can I learn more about UNWEB? Thanks
        Here's what you need...
        sub unweb { if($ENV{QUERY_STRING} eq "") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{QUERY_STRING}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ s/~!/ ~!/g; $FORM{$name} = $value; } return %FORM; }
        Have a look at cgi101. That's where I started with CGIs.
Re: Calling a sub-routine in CGI
by physgreg (Scribe) on Aug 09, 2002 at 03:08 UTC
    You could try
    print "<a href='".toggle_on()"'>ON</a>";
    Without knowing what toggle_on does. Are you trying to access the subroutine via the web page link? If so, it is not so straightforward, as you have to get the name from a form submission. Then you could have a hash of subroutine references, and if the form submission is in your list, then run it. In which case a bit of code like:
    print "<a href='$BASE_URL?action=toggle_on'>ON</a>";
    will be what you want in your HTML, where $BASE_URL is set to the appropriate link for your script. I would suggest having a look at CGI.pm for an easy way to deal with form submissions. Hope that helps!
Re: Calling a sub-routine in CGI
by Anonymous Monk on Aug 09, 2002 at 03:34 UTC
    This is the source I'm using, the sub routines work if I call them explicitly, but I wan't to call them from a link on the same page
    #!perl.exe -wT use Strict; use CGI; my $q = new CGI; print $q->header("text/html"); print <<WEB_PAGE; <HTML> <HEAD> <TITLE>Help ME</TITLE> </HEAD> <H1> Just a simple page for now </H1> WEB_PAGE my ($device, $port, $house, $unit, $interface); # Use BEGIN so we can conditionally eval modules BEGIN { # Set the parameters $interface = 'CM11'; $port = 'COM1'; $house = 'A'; $unit = '2'; use Win32::SerialPort 0.17; die "$@\n" if ($@); $device = Win32::SerialPort->new ($port) or die "Can't start $port +\n"; eval "use ControlX10::CM11 qw( :FUNC 2.06 )"; die "$@\n" if ($@); } $BASE_URL = '/cgi-bin/lights.cgi'; print "Turn light <a href='$BASE_URL?action=toggle_on'>ON</a>"; # &toggle_on; # &toggle_off; sub toggle_on{ my $cmd = 'J'; print"<h2>Turning Lights ON</H2>"; print "---> Toggle light $house$unit to on \($cmd\)\n"; send_cm11($device, $house . $unit); send_cm11($device, $house . $cmd); } sub toggle_off{ my $cmd = 'K'; print"<h2>Turning Lights OFF</H2>"; print "---> Toggle light $house$unit to on \($cmd\)\n"; send_cm11($device, $house . $unit); send_cm11($device, $house . $cmd); }
Re: Calling a sub-routine in CGI
by Anonymous Monk on Aug 09, 2002 at 11:23 UTC
    Thanks everyone, I guess I'm going about this the wrong way! (see my code mid way down the page) As I said I'm still learning CGI, and this is my first undertaking. Is there a better way to execute the toggle_on command? If so what are my options?

    The toggle_on comand in using the ControlX10 module from CPAN to activate some X10 components. Would it be better and less complicated to just create some sort of form and exexcute the command based on text input, or is it possible (I know anything is possible with Perl) to activate the sub-routine graphically (ie pushing a button, or clicking a hyperlink)?

    Thanks again

      So, you are wanting a web frontend to control some device connected through a serial port. This seems to imply that the machine with the serial port is the same one as running the webserver (it may be that all your software is running on one box).

      I would suggest that you are biting off more in one go than you can chew.

      I would suggest starting by writing a command line Perl program to drive the X10 stuff. Write this program in a modular fashion with subs for each of the functions.

      Next think about your web interface. Design the front end forms and hyperlinks, and prototype how you want it to work.

      Now knock up a small CGI app to call your existing program functionality using system or backticks. You should now have a working application!

      Finally, rewrite the CGI application to call the code directly.

      Hope this helps,

      --rW

        Thanks, I have completed your recommendation previously, but I'm having trouble calling the sub-routines via the CGI script. See code several posts above.

        I guess I will have learn some more CGI before I can proceed, thanks again everyone, you've given me plenty of ideas

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2024-04-18 03:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found