Problem Solution Discussion Performing Searches and Presenting the Results

print Image name:br print input type=\text\ name=\image_name\, size=\60\ print br print Image file:br print input type=\file\ name=\upload_file\, size=\60\ print br br print input type=\submit\ name=\choice\ value=\Submit\ print form When t he user subm it s t he form , it s cont ent s can be obt ained using t he FieldStorage m et hod of t he cgi m odule. See Recipe 18.6 . The result ing obj ect cont ains an elem ent for each input param et er. For a file upload field, you get t his inform at ion as follows: form = cgi.FieldStorage if form.has_key upload_file and form[upload_file].filename = : image_file = form[upload_file] else: image_file = None According t o m ost of t he docum ent at ion t hat I have read, t he file at t ribut e of an obj ect t hat corresponds t o a file field should be t rue if a file has been uploaded. Unfort unat ely, t he file at t ribut e seem s t o be t rue even when t he user subm it s t he form but leaves t he file field blank. I t m ay even be t he case t hat t he type at t ribut e is set when no file act ually was uploaded for exam ple, t o applicationoctet-stream . I n m y experience, a m ore reliable way t o det erm ine whet her a file really was uploaded is t o t est t he filename at t ribut e: form = cgi.FieldStorage if form.has_key upload_file and form[upload_file].filename: print pA file was uploadedp else: print pA file was not uploadedp Assum ing t hat a file was uploaded, access t he param et ers value at t ribut e t o read t he file and obt ain it s cont ent s: data = form[upload_file].value See t he post _im age.py script for det ails about how t o use t his funct ion t o get im age inform at ion and st ore it in MySQL.

18.10 Performing Searches and Presenting the Results

18.10.1 Problem

You want t o im plem ent a web-based search int erface.

18.10.2 Solution

Present a form cont aining fields t hat allow t he user t o supply search param et ers such as keywords. Use t he keywords t o const ruct a query, t hen display t he result s.

18.10.3 Discussion

A script t hat im plem ent s a web- based search int erface provides a convenience for people who visit your web sit e because t hey dont have t o know any SQL t o find inform at ion in your dat abase. I nst ead, visit ors supply keywords t hat describe what t heyre int erest ed in and your script figures out t he appropriat e queries t o run on t heir behalf. A com m on paradigm for t his act ivit y involves a form cont aining one or m ore fields for ent ering search param et ers. The user fills in t he form , subm it s it , and receives back a new page cont aining t he records t hat m at ch t he param et ers. The issues t hat you as t he writ er of t he script m ust handle are: • Generat e t he form and send it t o t he users. • I nt erpret t he subm it t ed form and const ruct a query from it s cont ent s. This includes proper use of placeholders or quot ing t o prevent bad input from crashing your script . • Displaying t he query result . This can be sim ple if t he result set is sm all, or m ore com plex if it is large. I n t he lat t er case, you m ay want t o present t he m at ching records using a paged display—t hat is, a display consist ing of m ult iple pages, each of which shows a subset of t he ent ire query result . Mult iple- page displays have t he benefit of not overwhelm ing t he user wit h huge am ount s of inform at ion all at once. They are discussed in Recipe 18.11 . This sect ion dem onst rat es a script t hat im plem ent s a m inim al search int erface: a form wit h one keyword field, from which a query is const ruct ed t hat ret urns at m ost one record. The script perform s a t wo- way search t hrough t he cont ent s of t he states t able. I f t he user ent ers a st at e nam e, it looks up t he corresponding abbreviat ion. Conversely, if t he user ent ers an abbreviat ion, it looks up t he nam e. The script , search_st at e.pl, looks like t his: usrbinperl -w search_state.pl - simple search for state application Present a form with an input field and a submit button. User enters a state abbreviation or a state name into the field and submits the form. Script finds the abbreviation and displays the full name, or finds the name and displays the abbreviation. use strict; use lib qwusrlocalapachelibperl; use CGI qw:standard escapeHTML; use Cookbook; my title = State Name or Abbreviation Lookup; print header , start_html -title = title, -bgcolor = white; Extract keyword parameter. If its present and nonempty, attempt to perform a lookup. my keyword = param keyword; if defined keyword keyword ~ \s { my dbh = Cookbook::connect ; my found = 0; my s; first try looking for keyword as a state abbreviation; if that fails, try looking for it as a name s = dbh-selectrow_array SELECT name FROM states WHERE abbrev = ?, undef, keyword; if s { ++found; print p You entered the abbreviation: . escapeHTML keyword; print p The corresponding state name is : . escapeHTML s; } s = dbh-selectrow_array SELECT abbrev FROM states WHERE name = ?, undef, keyword; if s { ++found; print p You entered the state name: . escapeHTML keyword; print p The corresponding abbreviation is : . escapeHTML s; } if found { print p You entered the keyword: . escapeHTML keyword; print p No match was found.; } dbh-disconnect ; } print p qq{ Enter a state name into the form and select Search, and I will show you the corresponding abbreviation. Or enter an abbreviation and I will show you the full name. }; print start_form -action = url ; print State: ; print textfield -name = keyword, -size = 20; print br , submit -name = choice, -value = Search, end_form ; print end_html ; exit 0; The script first checks t o see if a keyword param et er is present . I f so, it runs t he queries t hat look for a m at ch t o t he param et er value in t he states t able and displays t he result s. Then it present s t he form so t hat t he user can ent er a new search. When you t ry t he script , youll not ice t hat t he value of t he keyword field carries over from one invocat ion t o t he next . That s due t o CGI .pm s behavior of init ializing form fields wit h values from t he script environm ent . I f you dont like t his behavior, t o defeat it and m ake t he field com e up blank each t im e, supply an em pt y value explicit ly and an override param et er in t he textfield call: print textfield -name = keyword, -value = , -override = 1, -size = 20; Or else clear t he param et ers value in t he environm ent before generat ing t he field: param -name = keyword, -value = ; print textfield -name = keyword, -size = 20;

18.11 Generating Previous-Page and Next-Page Links