Page 13
Match Making (The Meat of the Matter)
Now that you've mushed your users' input around like Play-Doh, it's about time you give them something in return. Since your database doesn't have any real formatting of its own, drop the HTML formatting around the text you retrieve. Printing out to a Web page is just like printing out to standard output, except you can use HTML tags. The one thing you need to do when you print out to a Web page is tell the browser what it's getting in return. In this case, it's getting HTML, so you need to add ...
Content-Type: text/html\n\n
... in the first print statement sent out to the user. The user won't see it, but the browser will, and that's the important thing. (But make sure you send it out on only the first print, or the user will actually see it. It'd be lame to have Content-Type: text/html\n\n printed a thousand times all over the page. So with that one exception, we'll print the header of our results page like so:
Notice that I used HTML within my CGI. It's just like writing a normal HTML page in fragments, except this is done with print tags. I can make it as complicated as I want to, using every single HTML tag in the book, but we're learning CGI, not HTML, so I'm just showing you enough to give you the picture. Got it?
OK, so we've set up the header. That's super keen, but we haven't bitten into the meat (or the potatoes, if you're a veggie) of the script just yet. We still need to display the information the user is looking for. So far we have the user info in one variable and the database stored in an array variable. Now we need to run through the array and try to match the titles. If a title is matched, we'll print out the info; if it's not, we'll print out an error message.
What's the best way to run through an array? Well, you could use a for or a foreach loop. I get a personal sense of gratification when I use a for loop, so that's what I'm going to use here, although either is acceptable.
for ($i = 0; $i <= $#data; $i++) {}
This runs through the slots in @data until no slots are left. Then it quits. Now we need to check whether the title is stored in an entry.
if ($data[$i] =~ /-- $movie{'title'} --/i) {}
If there is indeed a match, we'll use something like the following code inside the if:
What we've done here is find the correct title by using the line of dashes I placed in the formatting of my database files, and that's line $i. The actual content we want to display, the title and the review, is found in the two lines after the dashed line. We'll print out that content by adding 1 or 2 to the $i variable. Once again we'll surround the output with HTML formatting to make it all pretty. So if the dashed line was on line 32, $i would be set to 32. To get the title of the movie without the dashed line, you would add 1 to $i because it is on the line below: line 33. To get the review of the movie, which resides in the third line of my database entry, line 34, you'd have to add 2 to $i. However, note that we're using a mathematical operator, not an assignment operator. So the value of $i would still be equal to 32. Once it prints out the information, it uses the "last" statement to tell the script that it's got what it needs. Essentially, "last" tells the loop that the pass it's on is the last pass, so it should break out and quit the loop.
Of course, the above scenario assumes that the information requested is actually found within the little database we've constructed. That's not always the case. What if the user requested some obscure German film from 1928? Chances are you don't have it in there. You get bonus points if you do; major bonus points. But let's say you don't. You need to add another statement to take care of that. This job would best be handled as an "elsif" statement appended on to the if written above. That way, it would be triggered only if the script was on its very last pass and hadn't found a match yet.
This code says if $i equals the number of slots in @data and the title wasn't in that slot, then do whatever. But what is whatever? It's always better to come right out and tell users that you don't have what they're looking for than to lie to them about it. Of course, the final decision is really up to you. So, between the brackets is where you explain why their searches aren't providing any results.
print "<b><i>Sorry! I haven't reviewed that one yet!</i></b>";
And with that written, you're done with the bulk of the script. Here's how the thing looks all together:
for ($i = 0; $i <= $#data; $i++) { if ($data[$i] =~ /-- $movie{'title'} --/i) { print <<END; <b><font size="+1">$data[$i + 1]</font></b><br> $data[$i + 2]<br> END last; } elsif ($i == $#data) { print "<b><i>Sorry! I haven't reviewed that one yet!</i></b>"; } }
Finish things off with the footer, which you address just like you did the header: