Welcome to WebmasterWorld Guest from 188.8.131.52
Is there any operational or security reason to use one over another? Aside from the fact that the hidden input is viewable in the source?
Session data doesn't fly between browser and server; it stays on the server (it may have, at some time, originated from a post or get). POST or GET data is transmitted from the browser to the server. You can never trust data that comes from "the outside" - it always has to be validated against either malicious intent or inadvertent inaccuracy. As an example, ask a user to input today's date. That user may enter the wrong date entirely, in a format that you don't expect to receive, some prankster may hope to corrupt (or obtain) your database through SQL injection, or a 3rd party may be sniffing around in hopes of receiving information valuable to him/her, the visitor, or you.
So if it's information you want to associate with a visitor and you can generate/retrieve it yourself, it's better to keep it in a session - it doesn't fly around and it's information you can trust - if it's info you received from a visitor, you've supposedly already validated it/rendered it harmless. If it's information that you're receiving from a visitor, POST and GET are the only vehicles (via internet anyway) so you're pretty much stuck with trying to make sure it's valid and harmless.
The hidden input isn't only viewable in the source, it can be modified before it gets sent back to you - so you have to validate it again.
The problem with sessions is that we use them and send user supplied data to them. This allows attackers to hijack the sessions. So while a session is infinitively more secure than a hidden variable, you do have to work to make sure that your use of the sessions is as secure as the php back end.
There are a lot of good articles on the web about trying to secure your sessions. So if you are going to be using them then it is well worth reading up about session security [uk.php.net].
If you keep track of the product ID in the SESSION, the ID for widget B will overwrite the one for widget A and the visitor ends up ordering the wrong thing (unless you create a separate session for each form). If you store the product ID in a hidden value, then all is fine. On the other hand, you probably want to keep the current contents of the visitor's shopping cart in the SESSION variable so that items can be added from any open window.