简体   繁体   中英

Correctly Programming in Perl CGI / Accessing the same data from differ perl cgi files

I am new to Perl CGI programming and have a few questions. Currently I have 1 HTML page and a bunch of perl pages. The users starts on an HTML page where they enter their name and address. This form then calls a Perl CGI file. Now when this Perl file executes it generates some HTML that the user will see as another page. Now inside the HTML that was generated by the perl file there is another form that calls another CGI script. This continues so that I basically have a Perl CGI file for every page.

Is this the correct way to do things with CGI?

The problem I am having with this is that I don't know how to share information around all these perl files as they only communicate with each other through the actions of forms.

I have a small shopping cart and therefore need to be able to initialize, get and set the contents of it from multiple pages.

How can I share data between the files as I described above?

To re-iterate what Sinan said, the shopping cart needs to be done using sessions.

I will try to explain a bit more about how it all works, since your question seems to imply you would like to understand the details.


There are two concepts that are involved: A Session Cookie, and a Session database on the server side.

Your web server has an internal "sessions" database - which is basically a mapping between a long string known as the "Session Key" and a blob of data. This database can be built into the web server, or in case of Perl CGI, be implemented by a special Perl module.

What gets stored in this blob of data in a Session database? Anything your CGI script decides to store - in your case, the current state of the shopping cart.

How does the information get shared between the pages? A special " Session Cookie " is generated by your session module, with the value of the cookie being the same "Session Key" used to store the blob of data on the server in session database. It is then stored by the user's browser like all the other cookies, except its value is only valid "for the duration of a session" - it expires after a short period of time or if you close your browser. Then, when the user continues with the web app, the cookie value gets sent back to the server and therefore your CGI script knows to re-use that session key.

NOTE : An alternate approach (instead of using a cookie) is to pass the session ID value between all your requests (eg code it into all GET URLs and POST forms).


As far as Perl CGI implementation, it depends on the specific Perl web framework you use - the basic session work can be done using CGI::Session CPAN module (there is a good tutorial for it as well ). Another frequent option for those using Apache web server is Apache::Session .

What a general Session related module does is provide you with the APIs to:

  • Manage Session database
  • Store/retrieve data in Session database using Session key (aka Session ID)
  • Obtain the user's current session ID (from the session cookie value), if any
  • Generate a new session ID for the user, if needed
  • Send the session ID value as a cookie to be stored in HTTP response to user's browser.

Any decent Perl web framework has session capabilities built in (they are still implemented using some sort of Session management Perl module, but the framework provides easy-to-use APIs.

As an example of "easy to use", in Embperl, to store a value in a session, all you do is $udat{shopping_cart} = \\%shopping_cart_data and to retrieve it you do %shopping_cart_data = %$udat{shopping_cart} - %udat being a special hash name). That's it. All the details hidden from you by the framework.


UPDATE:

This has pretty much nothing to do with what seems to me the actual question being asked, but it's nevertheless a valid point that a comment to this answer made me think of.

In the interest of improving the overall quality of your code, you should always abstract away as much of the general business logic. In this case, if you have any generic logic for working with the shopping cart data which is shared between your different Perl CGI scripts, that logic should be abstracted away into a separate Perl module.

In addition, as further improvements:

  • You should consider MVC (model-view-controller) design for any complicated web app. To make this easier, pick an MVC-compliant Perl web framework (I think Catalyst is considered the main option these days but do your own research before setting on one.

  • You should also have a design that allows you to modularize and re-use web (view) elements - eg the top var of the application that probably will display # of items in the shopping cart would always be pretty much the same HTML, and you should not duplicate that HTML across different views. (if you aren't sure what I'm talking about, look at top 2 lines on Amazon's web page). There are different techniques for achieving that, which go well beyond the scope of your question (frames, web frameworks with merged views, Perl module for View printing, etc...).

The short answer is: You are doing it all wrong.

You need to store the contents of the shopping cart for each visitor on the server side using server side sessions.

See, for example, My Experiences with using CGI::Application and Template::Toolkit To Build an Online Shopping Cart by Justin Simoni .

If you try to store the contents of the shopping cart in HTML pages you serve, malicious visitors can easily change, say, prices and give themselves nice discounts as people discovered in the mid nineties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM