【问题标题】:is each session call is separate call to server每个会话调用是对服务器的单独调用吗
【发布时间】:2013-10-01 14:49:22
【问题描述】:

考虑到服务器负载,我想知道每次对会话的调用是否都是对服务器的单独调用,这会增加服务器负载? 让我稍微解释一下。假设在每个 php 页面中,我必须设置 10 个会话数据,并且必须像这样调用 10 个会话数据:

$_SESSION['a']=1;
$_SESSION['b']=2;
$_SESSION['c']=3;
$_SESSION['d']=4;
$_SESSION['e']=5;
$_SESSION['f']=6;
$_SESSION['g']=7;
$_SESSION['h']=8;
$_SESSION['i']=9;
$_SESSION['j']=10;

echo $_SESSION['a'];
echo $_SESSION['b'];
echo $_SESSION['c'];
echo $_SESSION['d'];
echo $_SESSION['e'];
echo $_SESSION['f'];
echo $_SESSION['g'];
echo $_SESSION['h'];
echo $_SESSION['i'];
echo $_SESSION['j'];

设置上述 10 个会话并输出相同,这些是对服务器的 20 个单独调用还是通过 session_start(),在页面加载期间一次性加载整个会话数据?

还想知道如何在会话中存储多维关联数组?假设我想这样设置上面的 10 个会话数据:

$_SESSION['mydata']=array(
a=>1,
b=>2,
c=>3,
d=>4,
e=>5,
f=>6,
g=>7,
h=>8,
i=>9,
j=>10
)

echo $_SESSION['mydata']['a'];

通过上面的例子,如果每个会话调用都是对服务器的单独调用,我可以减少服务器负载。

有人告诉我设置和获取会话数据时发生了什么吗?

【问题讨论】:

  • PHP 代码全部在服务器上。
  • 您了解会话数据的实际含义吗?通过将数据保存在用户特定的“会话”中而在服务器调用之间持久保存的数据?
  • 这确实提出了一个有趣的问题...$_SESSION 超全局,当会话被实例化时所有数据是否完全传播(将所有数据保存在内存中)或者是否有文件系统读取每次访问 $_SESSION 时保存在 /tmp 中的会话文件(默认情况下)?我以前从未真正考虑过。
  • SLaks,我知道 php 是服务器端代码。但我告诉过,由于会话本身是一个关联数组,所以当我们通过 session_start 启动会话时,无论是在 php 脚本加载期间所有存储的会话同时加载还是像 $_SESSION['a'] 这样调用每个会话都会单独调用服务器?
  • @stockBoi - 好的,会话 101。调用 session_start()(或脚本的状态,如果会话设置为自动启动)从会话的永久存储(通常是文件系统)读取数据并填充超全球 $_SESSION。如果之前不存在会话,则会创建一个空的 $_SESSION。对 session_write_close() 的调用或脚本的终止会将 $_SESSION 的内容写入会话的永久存储...在这之间,它保存在 $_SESSION 的内存中

标签: php session


【解决方案1】:

这是一个会话的细分

  • session_start(); 要么在硬盘上创建一个会话文件,要么访问一个已经存在的会话文件。是一个序列化的数组
  • 该数组被加载到内存中并在内存中进行操作,直到脚本完成执行,或者您可以使用session_write_close() 强制它重新写入文件

您可以在开始会话后添加/删除任意数量的数据,因为这与操作数组没有什么不同。

繁重的工作在session_startsession_write_close 完成,因为那是 PHP 实际必须访问硬盘的时候

理论上每个用户可以在 FAT32 服务器上拥有一个 4GB 的会话文件,或者在 NTFS 服务器上拥有更大的会话文件,但我相信您可以想象会出现可怕的性能问题。

【讨论】:

    【解决方案2】:

    脚本的整个执行都是在一个请求中完成的。通过设置 $_SESSION['foo']='bar' 和 $_SESSION['baz']='biz' 您不会设置两个不同的会话,而是设置两个会话变量

    所以整个会话是在脚本启动上加载的,而不是页面加载(这是一个客户端术语)。

    这一切都是通过 cookie 完成的。

    编辑,回答您的评论:

    正如其他人提到的(请参阅 Mark Ba​​ker 的评论),会话在脚本启动之前加载一次,并在脚本结束后存储一次(除非您明确调用 session_write_close()

    当然,尺寸很重要。显然,会话越大,加载/存储所需的时间就越长。但这将是您最不想优化的事情。

    【讨论】:

    • 让我们解释一下。假设我在一个 php 页面 page01.php 中包含两个文件 include('filea.php') 和 include('fileb.php')。然后当脚本/页面 page01.php 开始执行时,这两个包含将是对服务器的两个单独的读取操作,这会在服务器上创建负载。这就是为什么如果我们想减少服务器负载,我们应该减少每个 php 脚本的包含。这是我对会话的关注。
    【解决方案3】:

    会话基准

    对于$_SESSION['mydata']['key'] = 'value'

    session_start();
    $time_begin = microtime(true);
    $mem_start = memory_get_usage();
    for ($i=0; $i < 100000; $i++) { 
    $_SESSION['mydata']["a$i"] = $i;
    }
    foreach ($_SESSION['mydata'] as $key => $value) {
        $r = $value;
    }
    $mem_end = memory_get_usage();
    $time_end = microtime(true);
    echo "Time :";
    echo  $time_end - $time_begin;
    echo "<br>";
    echo "Memory :";
    echo  $mem_end - $mem_start;
    

    我关于$_SESSION['mydata']['key']的结果:

    Time :0.57849311828613
    Memory :464
    

    对于$_SESSION['key'] = 'value'

    <?php
    
    session_start();
    
    $time_begin = microtime(true);
    $mem_start = memory_get_usage();
    for ($i=0; $i < 100000; $i++) { 
        $_SESSION["a$i"] = $i;
    }
    for ($i=0; $i < 100000; $i++) { 
        $r = $_SESSION["a$i"];
    
    }
    $mem_end = memory_get_usage();
    $time_end = microtime(true);
    echo "Time :";
    echo $time_end - $time_begin;
    echo "<br>";
    echo "Memory :";
    echo $mem_end - $mem_start;
    

    我关于$_SESSION['mydata']的结果:

    Time :0.47217416763306
    Memory :176
    

    已编辑:在 mydata 数组和另一个 mydata 的键所花费的第一个 PHP 脚本内存中。所以,第二种方式再次更大。

    所以,使用$_SESSION['key'] = 'value' 大于$_SESSION['my']['key'] = 'value'

    这可能是当你想为 $_SESSION['my']['key'] 设置一个值时,php 应该得到$_SESSION['my'] 并且之后可以创建新变量的原因。在$_SESSION['my']['key']

    【讨论】:

    • 解决了语法问题,但您未能回答 OP 的问题:“有人告诉我我们设置和获取会话数据时发生了什么吗?”
    • 对不起,这可能很糟糕,我根据您的问题编辑了我的答案。
    • 感谢 Dalim 的实践考试。但是服务器负载不能仅通过执行时间来衡量。也许一个 php 对象执行速度很快,但它使用了更高的服务器内存。
    • 我添加了一些代码来显示内存使用情况。请检查一下。
    猜你喜欢
    • 2013-01-04
    • 2019-12-24
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 2016-02-13
    • 1970-01-01
    相关资源
    最近更新 更多