php 购物车持久化:$_SESSION 还是浏览器 cookie?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12569568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Shopping cart persistence: $_SESSION or browser cookie?
提问by Xeoncross
On an e-commerce site with no username/login to persist cart data, would it be better to use the PHP $_SESSION variable or a browser cookie to persist items in the shopping cart? I am leaning toward $_SESSION since cookies can be disabled, but would like to hear thoughts from you.
在没有用户名/登录名来保存购物车数据的电子商务网站上,使用 PHP $_SESSION 变量或浏览器 cookie 来保存购物车中的商品会更好吗?我倾向于 $_SESSION,因为可以禁用 cookie,但想听听您的想法。
Thank you in advance for your consideration.
预先感谢您的考虑。
回答by Xeoncross
Neither
两者都不
No large sites would dare store a user's cart in a session or cookie - that data is just to valuable.
没有大型网站敢将用户的购物车存储在会话或 cookie 中——这些数据非常有价值。
What customers are buying, when they select items, how many they purchase, why they don't finish the checkout, etc.. are all very, veryimportant to your business.
客户在购买什么、他们何时选择商品、他们购买了多少商品、为什么他们没有完成结账等等,这些对您的业务来说都非常非常重要。
Use a database table to store this information and then link it to the user's session. That way you don't lose the information and you can go back and build statistics based on users carts or solve problems with your checkout process.
使用数据库表来存储此信息,然后将其链接到用户的会话。这样您就不会丢失信息,并且您可以返回并根据用户购物车建立统计数据或解决结账过程中的问题。
Log everything you can.
记录你能做的一切。
Database Schema
数据库架构
Below is a simplified example of how this might look at the database level.
下面是一个简化的示例,说明这可能如何看待数据库级别。
user {
id
email
}
product {
id
name
price
}
cart {
id
product_id
user_id
quantity
timestamp (when was it created?)
expired (is this cart still active?)
}
You might also want to split the cart table out into more tables so you can track revisions to the cart.
您可能还想将购物车表格拆分为更多表格,以便跟踪购物车的修订。
Sessions
会话
Normal PHP Sessions consist of two parts
正常的 PHP Sessions 由两部分组成
- The data (stored in a file on the server)
- A unique identifier given to the user agent (browser)
- 数据(存储在服务器上的文件中)
- 给用户代理(浏览器)的唯一标识符
Therefore, it's not $_SESSIONvs $_COOKIE- it's $_SESSION+$_COOKIE= "session". However, there are ways you can modify this by using a single encrypted cookie which contains the data (and therefore you don't need an identifier to find the data). Another common approach is to store the data in memcached or a database instead of the filesystem so that multiple servers can access it.
因此,它不是$_SESSIONvs $_COOKIE- 它是$_SESSION+$_COOKIE= "session"。但是,您可以通过使用包含数据的单个加密 cookie 来修改它(因此您不需要标识符来查找数据)。另一种常见的方法是将数据存储在 memcached 或数据库而不是文件系统中,以便多个服务器可以访问它。
What @Travesty3 is saying is that you can have twocookies - one for the session, and another that is either a "keep me logged in" cookie (which exists longer than the session cookie), or a copy of the data inside separate cookie.
@Travesty3 的意思是你可以有两个cookie - 一个用于会话,另一个是“保持登录状态”cookie(存在时间比会话 cookie 长),或者是单独 cookie 中的数据副本.
回答by MukeshD
As pointed out by Xeoncross, it is very important to store any possible information for analysis. So one should not entirely rely on sessions and cookies.
正如 Xeoncross 所指出的,存储任何可能的信息以供分析非常重要。因此,不应完全依赖会话和 cookie。
A possible approach is-
一种可能的方法是——
Use sessions if not logged in
如果未登录,请使用会话
If the user is not logged in, you can store and retrieve the cart items and wishlist items from session using $_SESSIONin PHP
如果用户未登录,您可以使用$_SESSIONPHP从会话中存储和检索购物车项目和愿望清单项目
Use database when logged in
登录时使用数据库
If the user is logged in then you can consider one of the two options -
如果用户已登录,则可以考虑以下两个选项之一 -
- Store the cart item or wishlist item in database alone
- Store the cart item or wishlist item in database as well as in session (This will save some of your database queries)
- 将购物车项目或心愿单项目单独存储在数据库中
- 将购物车项目或心愿单项目存储在数据库和会话中(这将保存您的一些数据库查询)
When user logs in
当用户登录时
When the user logs in, get all the cart items and wishlist items from the session and store it in the database.
当用户登录时,从会话中获取所有购物车项目和愿望清单项目并将其存储在数据库中。
This will make the data persistent even if the user logs out or changes the machine but till the user has not logged in, there is no way to store the information permanently so it will not be persistent.
这将使数据持久化,即使用户注销或更换机器,但直到用户没有登录,没有办法永久存储信息,因此它不会持久化。
Getting required data
获取所需数据
Whenever you are trying to access cart or wishlist do the following check -
每当您尝试访问购物车或心愿单时,请执行以下检查 -
- If the user is not logged in then look into session
- If the user is logged in, query database if you are storing in the database alone, otherwise you can just look into sessions if you are keeping session updated along with the database
- 如果用户未登录,则查看会话
- 如果用户已登录,如果您单独存储在数据库中,则查询数据库,否则,如果您将会话与数据库一起更新,则可以查看会话
回答by JvdBerg
I would store it in a SESSION. My wish list is rather long, and I am afraid that it will not fit in the 4K storage that a COOKIE may occupy. It forces you set the session time out to a longer period.
我会将它存储在 SESSION 中。我的愿望清单比较长,怕是放不下一个COOKIE可能占用的4K存储空间。它强制您将会话超时设置为更长的时间。
note: there are some countries (like the Netherlands, where I am) that have very strict policies about cookies, and you may be forced by legislation to use Sessions.
注意:有些国家(如我所在的荷兰)对 cookie 有非常严格的政策,您可能会被立法强制使用 Sessions。
回答by Ricardo Souza
Some points to help:
一些帮助点:
Cookies:
饼干:
- info is persisted untill the cookie expires (what can be configured by you);
- tend to slow down the communication between server and client, since it has to be exchanged between the two in every request/response;
- its an insecure form of storing data and easy to sniff;
- they also have a limit to store data.
- 信息会一直保留到 cookie 过期(您可以配置什么);
- 往往会减慢服务器和客户端之间的通信速度,因为它必须在每个请求/响应中在两者之间进行交换;
- 它是一种不安全的数据存储形式,易于嗅探;
- 它们也有存储数据的限制。
Session:
会议:
- all information is persisted in the server, thus not been exchanged with the client.
- because it is not shared across the network, its a bit more secure;
- all info is lost when the session ends;
- If you are hosting in a shared host, you may have problems with session ending in the middle of a operation due to a push on the resources by any of the sites hosted on the same server.
- 所有信息都保存在服务器中,因此不会与客户端交换。
- 因为它不是跨网络共享的,所以它更安全一些;
- 会话结束时所有信息都将丢失;
- 如果您在共享主机上托管,由于托管在同一服务器上的任何站点对资源的推送,您可能会遇到会话在操作中间结束的问题。
I would personally go with sessions, since I'm assuming to be a small/meddium auddience page. If it grows, you would be better with a simple DB structure to store this data, with a maintenance plan to get ridge of unnecessary data (eg: clients that choose some products but don't do the checkout).
我个人会参加会议,因为我假设是一个中小型观众页面。如果它增长,您最好使用简单的数据库结构来存储这些数据,并制定维护计划以消除不必要的数据(例如:选择某些产品但不结账的客户)。
回答by Travesty3
You might consider using both.
您可以考虑同时使用两者。
The drawback with $_SESSIONis that the session is cleared when the browser is closed.
缺点$_SESSION是当浏览器关闭时会话被清除。
Use sessions, but attempt to populate the $_SESSION data from a cookie, if it's available.
使用会话,但尝试从 cookie 填充 $_SESSION 数据(如果可用)。
回答by batfastad
I would use a session. If a user has cookies disabled then the session won't be able to start as the session ID is stored on the user's machine in a cookie.
我会使用会话。如果用户禁用了 cookie,则会话将无法启动,因为会话 ID 存储在用户计算机上的 cookie 中。
There are some settings you may want to look at in order to attempt to keep the sessions for longer.
您可能需要查看一些设置以尝试将会话保留更长时间。
Prevent the session cookie from being deleted when the user closes their browser by running
session_set_cookie_params()with thelifetimeparameter set. This function needs to run beforesession_start()You may also want to extend how often sessions are cleared from the server by modifying the session garbage collection settings
session.gc_probability, session.gc_divisor, session.gc_maxlifetimeeither in php.ini or usingini_set()If you have other websites running on the server and you modify the above garbage collection settings you will need them set in php.ini so they apply to all websites, or if you are using
ini_set()then you might also look at saving these sessions to a different directory than other websites by modifyingsession_save_path(). Again this is run beforesession_start(). This will prevent the garbage collection of other websites clearing up your extended sessions for one particular site.I would also recommend setting the following session settings in php.ini
session.entropy_file = /dev/urandom, session.entropy_length = 256, session.hash_function = sha512. That should give you a cryptographically strong session ID with an extremely tiny chance of collisions.And make sure you have an SSL cert on your site to prevent man in the middle attacks against your session ID.
通过
session_set_cookie_params()使用lifetime参数集运行,防止在用户关闭浏览器时删除会话 cookie 。这个函数需要先运行session_start()您可能还想通过修改
session.gc_probability, session.gc_divisor, session.gc_maxlifetimephp.ini 中的会话垃圾收集设置或使用ini_set()如果您在服务器上运行其他网站并且您修改了上述垃圾收集设置,您将需要在 php.ini 中设置它们,以便它们适用于所有网站,或者如果您正在使用,
ini_set()那么您也可以考虑将这些会话保存到不同的目录比其他网站通过修改session_save_path()。这又是在session_start(). 这将防止其他网站的垃圾收集清理您为一个特定网站的扩展会话。我还建议在 php.ini 中设置以下会话设置
session.entropy_file = /dev/urandom, session.entropy_length = 256, session.hash_function = sha512。这应该会给你一个加密强的会话 ID,冲突的可能性极小。并确保您的站点上有 SSL 证书,以防止中间人攻击您的会话 ID。
Obviously a user could still decide to manually clear all their cookies which will take the session ID cookie with it but that's a risk I'd be prepared to take. If I was halfway through a shopping cart system and hadn't checked out, I wouldn't go and clear my cookies. I still think sessions are better than just using plain cookies.
显然,用户仍然可以决定手动清除他们的所有 cookie,这将带走会话 ID cookie,但我愿意承担风险。如果我在购物车系统中途还没有结账,我就不会去清除我的 cookie。我仍然认为 session 比只使用普通的 cookie 更好。
The data is secure enough so long as you are the only website that has access to your sessions directory and your session ID is strong. And by extending the server's session storage time your data can persist on the server.
只要您是唯一可以访问会话目录且会话 ID 强的网站,数据就足够安全。通过延长服务器的会话存储时间,您的数据可以保留在服务器上。
There are further measures you could employ to make your sessions even stronger. Regenerate your session ID every 20 minutes, copying the data over. Also record session IDs against IP addresses in a database and check to see if a particular IP address attempts to send more than X number of session IDs in a given time to prevent someone trying to brute force a session ID.
您可以采取进一步的措施来使您的会话更加强大。每 20 分钟重新生成一次会话 ID,复制数据。还要根据数据库中的 IP 地址记录会话 ID,并检查特定 IP 地址是否尝试在给定时间内发送超过 X 个会话 ID,以防止有人尝试暴力破解会话 ID。
You could also store the data in a database linked by the session ID, instead of in a session file on the server. However this is still reliant on a session ID which is stored in a cookie and could disappear at any time. The only way to truly be sure that a user doesn't lose their cart is by having them login first and storing in a database.
您还可以将数据存储在由会话 ID 链接的数据库中,而不是存储在服务器上的会话文件中。然而,这仍然依赖于存储在 cookie 中并且可能随时消失的会话 ID。真正确保用户不会丢失购物车的唯一方法是让他们先登录并存储在数据库中。

