SimpleshoPHP

The Walkthrough

Part 2

To recap, here's our sample database entry for a single book (with column headings to help make sense of it):

TITLE             AUTHOR        PUBLISHER  FORMAT  PRICE  DEPT     SKU
My Life as a Frog Bill French   Madhouse   PB      7.95   Fiction  MLFBF01

We could duplicate all this information into our shopping cart/bookbag, but why bother? As long as we have the SKU, we can get it any time we want it. So, our "bag" table is very simple indeed:

SESS              SKU           QTY
a1234...def       MLFBF01       1

That's all we need in order to know that the session which PHP has identified with the tag "a1234...def" wants to purchase one copy of the book with SKU "MLFBF01".

To display the current contents of the bookbag, we use the database "join" command, given near the end of Part 1:

select (everything interesting) from books, bag
  where books.sku = bag.sku and sess = (the session we're in);

We don't want every book that is in every bag, so we limit it to the books that are also tagged with our current session ID. This is something that MySQL -- and indeed, every relational database -- understands very well indeed.

Displaying the bookbag seems like a natural thing to do each time our customer adds a new item. Adding an item to the bag is done by a bit of PHP code that does not display any HTML. Instead, the "addtobag" page inserts a new row into the bag table and does a redirect to the "bookbag" page. We have "addtobag" links on the browse page for people who know what they want, and on the flypage for people who want to see all the details before they buy. On the bookbag page we provide a link to a similar "rmfmbag" script to remove an item from the bag.

Cashing in

We can show our wares, and we can let customers pick items to put into their shopping bag. What's next? Ah, yes -- the sale. We need a way to collect their billing and shipping information, to report those (safely!) to our shopkeeper for "fulfillment," and it would make sense to reduce our inventory accordingly.

Before we ask for sensitive information, we can and should redirect the current session to an SSL (Secure Sockets Layer) connection. Everything the user sends us will be scrambled by her browser and not unscrambled until it's safely inside our server, and vice-versa.

Collecting the information is ordinary HTML; there are a few different kinds of input fields which any browser will handle in standard ways when asked. Combining that information with the content of the bookbag is also straightforward. Handling it safely, though -- that's a hurdle. We have three options:

Frankly, all three of these scare me to death; the solution is to pick the least frightening one. I do not want someone's credit card details in my database, waiting for some kid to crack it open and scoop out its juicy goodness. (There IS no "orders" or "customers" table in my database.) A flat file on the server is only as safe as the least secure password to any account on that server. Sending it in email is nuts from a security standpoint -- or is it? At least it would be a moving target!

PGP to the Rescue

Remember, once the server unscrambles the SSL session data, it's vulnerable again. We need a way to scramble our order information that is good enough to stand up to someone who can read our hard drive or intercept our email. Fortunately, we can arrange to have all that information securely encrypted before it ever hits the server's hard disk. That's where PGP comes in. PGP stands for Pretty Good Privacy, and was originally invented by Phil Zimmermann. It's now available as a commercial product, or as the freeware "GNU Privacy Guard," GPG.

The beauty of PGP is that it uses a key that has two parts. We can leave one key on the server (which would otherwise be like leaving your front door key under your doormat, as far as security goes) because it will only be used to scramble the file. The other key, the one that unscrambles files, will never, ever be on the server. It will be in an office somewhere, and will be used to unscramble and read the orders. Those orders can now be safely picked off the hard drive, read out of the database, or even sent as email. One conservative approach would be to send an email telling the seller only that there is a new order; the seller would log in to the server to pick up the order. Frankly, though, once we start using PGP encryption, sending an order through email is no longer a security issue. By the time even a determined and well-funded cracker breaks one order, that customer's credit card will have expired.

So: Buyer clicks on "checkout." The link to the checkout process is an "https" (secure or SSL) link, not just http. The checkout HTML form collects the buyer's information, combines it with the content of the bookbag, and "pipes" the resulting text into PGP using an encryption-only key that stays on the server (and which has no value to anyone trying to unscramble the file).

The resulting scrambled text is saved to disk and/or mailed to the order fulfillment person. She has the decryption (unscrambling) key and can read and process the order.

To keep things neat, the checkout process should also empty the bookbag and reduce the count of items "in stock" in our inventory -- though we may have already reduced the "in stock" counter as each item was added to the bookbag. (Many of the items at the pilot store are one-of-a-kind, so it wouldn't do to let someone even try to buy one of them twice.) An alternative is to keep a timestamp in the bookbag, and run a process to empty out old orders every night. That could be useful if a customer wants to think about an order for a while; it's a tradeoff -- the natural desire to save data until we are certain it's no longer needed, versus our desire to keep our database as small and uncluttered as possible.

That pretty much wraps up the high-level overview. Next we will look at actual code, starting with index.php, also known as main.php.


Summary

Detailed descriptions

SimpleshoPHP Home


You are invited to post comments or questions on the SimpleshoPHP forum at SourceForge.net.

SourceForge.net Logo


Copyright 2003-2005, Kevin Martin, dba Brass Cannon Consulting.
The project "SimpleshoPHP" is Free Software, distributed
under the LGPL as described at opensource.org