将会话状态保存为与其他人共享的唯一URL

I am using sessions to store items in a users wish list.

The wishlist is stored as a simple array of unique item ids - An average user would store around 40 items in the wish list but it is possible that a user may wish to add as many as a few hundred items in their wish list.

I would like to generate a unique URL so that they can revisit their wishlist later, or share the wishlist with others who could use it as a starting point for their own lists.

I am not collecting any data from the user, and they will not have an account to link their wishlist data with.

The 2 methods of dealing with this that I am considering are:

Storing the data as a hash on the end of the URL, either as a url encoded serialised string or base64 encoded string. This seems preferable as I will not need to store the wishlists and this offers a large amount of flexibility for users to modify existing lists, however I suspect that this will become unworkable if the number of items in the wishlist increases and the URL length grows beyond workable character counts.

OR

Generate a url with a unique Id and save the wishlist to the database. The problem I see with this is that a new entry will be added to the database every time a user wishes to generate a URL, and since these entries won't be tied to any one user, a new entry will need to be generated every time a user makes any modification to a list.

Is there another better approach to handling this, or a way to manage the problems associated with the above methods?

I think going the database route will be the most flexible solution in the long run. Adding/removing records every time a user makes a selection shouldn't be an issue as long as your data is well modeled. A "selection" should create no more than record referencing two things by key; a user, a product plus a quantity and price perhaps.

That said, I would do it with a model similar to this:

  • product (id, ...)
  • selection_set (id, name)
  • selection (product_id, selection_set_id, quantity, price)
  • wishlist (public_hash, selection_set_id)

Wishlist is separate from selection_set because you could reuse selection_set for other things, like a shopping cart or order.

Once that's done, you can just store the public_hash in a cookie/session and give them a url to link to.

Would that work for the scenario you had in mind? or are there any additional constraints?

Alternate solutions:

Even though I think the database is a viable solution, I can think of a couple of alternatives:

Zip and encode data:

You can take a comma separated list of wishlist item ids (or some sort of unique identifier), then base64_encode( gzinflate( $list ) ) and use that as your hash. You can then use gzdeflate( base64_decode( $hash ) ) to get your list of items. In order to avoid doing this on every page load, you can continue storing your selection within the session and only re-generate the hash when the list changes.

gzdeflate + base64 should keep your hash within reasoable lengths for up to very large wishlist selections. You can write some unit tests to see how long a hash/list can get hypothetically.

This method feels like a total hack :-)

Use Redis:

You can set up a redis server and store wishlists on it. It'll be persistent, scalable, fast and easy to access.