Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 为什么Symfony会在每次请求时从数据库重新加载用户?_Php_Symfony - Fatal编程技术网

Php 为什么Symfony会在每次请求时从数据库重新加载用户?

Php 为什么Symfony会在每次请求时从数据库重新加载用户?,php,symfony,Php,Symfony,来自Symfony 2食谱: 用户登录后,整个用户对象将序列化到 会议结束了。在下一个请求中,用户对象被反序列化。 然后,id属性的值用于重新查询新用户 对象从数据库中删除 以及 。。。实际上,这意味着用户对象从 使用序列化对象的id处理每个请求的数据库 为什么Symfony必须在每次请求时从数据库中获取用户对象 在什么情况下,存储在会话数据中的序列化用户对象会与从数据库中获取的用户对象不匹配?当然,Symfony知道用户对象何时更改,并且可以在发生更改时简单地更新会话数据 我想这是有充分理由的

来自Symfony 2食谱:

用户登录后,整个用户对象将序列化到 会议结束了。在下一个请求中,用户对象被反序列化。 然后,id属性的值用于重新查询新用户 对象从数据库中删除

以及

。。。实际上,这意味着用户对象从 使用序列化对象的id处理每个请求的数据库

为什么Symfony必须在每次请求时从数据库中获取用户对象

在什么情况下,存储在会话数据中的序列化用户对象会与从数据库中获取的用户对象不匹配?当然,Symfony知道用户对象何时更改,并且可以在发生更改时简单地更新会话数据

我想这是有充分理由的,因为在每次请求时不必要地查询数据库是浪费的。

免责声明:我不知道Symfony的具体情况,所以这是根据PHP的一般知识和一些假设编写的

PHP会话通常不能从外部进行操作——它们只是文件或内存存储中的一组序列化数据。改变一个会话的唯一方法是反序列化它,进行更改,然后重新序列化整个会话-通常只有在“处于”该会话中时才会这样做

因此,如果用户的详细信息在登录会话之外发生更改,序列化的blob将过期。这将是一个特殊的问题,例如,如果管理员吊销了用户的访问权限

诸如memcached之类的缓存可能存储每个用户的详细信息,并在编辑时显式刷新/更改,但这将被视为数据库获取的一部分(memcached层可以更快地访问数据库数据),而不是会话处理


正如haltabush在一篇评论中所问的:如果每个请求都获取了用户,那么为什么要序列化它呢

答案是,会话中需要存储足够的信息,以识别登录的用户,并在下一页加载时获取他们的完整详细信息。这可能与存储用户ID一样简单,但通过使用可序列化的接口,Symfony可以让特定的实现来决定哪些字段应该保存到会话中,哪些字段应该在未序列化时重新获取

它还允许实现将用户的所有详细信息保存到会话中,并在更轻松的基础上进行“刷新”,例如,在设定的时间或请求数之后,如上所述

在什么情况下,存储在会话数据中的序列化用户对象会与从数据库中获取的用户对象不匹配

例如,当管理员更改用户拥有的权限时–这通常是您希望立即生效的事情,而不仅仅是当用户注销然后下次再次登录时

当然,Symfony知道用户对象何时更改,并且可以在发生更改时简单地更新会话数据


当该更改与用户会话没有连接时,则不会出现这种情况,如上述场景中的情况。

我想补充,如果用户在每个连接上都被抓取,并且有很好的理由,为什么会在会话中序列化?@haltabush我已在我的答案中添加了对此的解释。在他们的文档页面上注明“这样可以确保用户的所有数据都是最新的。“覆盖用户提供程序并调整此行为相当容易。但是请记住,数据库在缓存这些类型的查询方面确实很有用。因此,您可能没有注意到任何性能改进。对于所有正在搜索当前Symfony版本文档的人来说:它已经移动到这个位置,完美地回答了我的问题,谢谢。我没有想到,如果Symfony只依赖会话数据,被撤销的特权可能不会立即生效;我没有考虑到撤销用户的权限不会影响会话数据。因为我只能接受一个答案,所以我必须先接受那个答案。@RichardKeller,事实上,那不完全是真的。在默认实现中,Symfony不会刷新每个请求的所有角色和权限。它检查用户名、salt和密码,尽管这可以通过实现AdvancedUserInterface或EqualTableInterface接口在userland代码中重写。请参阅AbstractToken::hasUserChanged()()