3

我知道将变量导入 PHP 的传统 $_POST 方法。但是,如果变量数量如此之多,这仍然是传递变量的最有效解决方案吗?

目前在我的代码中,用户将信息输入到 100 多个输入文本中,然后使用 $_POST 方法将此信息传递给 PHP。但是,我认为这对于许多服务器来说不会太好。

本质上,如果有人能告诉我将大量变量传递给服务器的理想方式,那就太好了。提前致谢。

编辑:

对于所有说这将只是一场 UI 灾难的人来说,这已经被多次咨询过。然而,提交页面本质上是网站的核心,用户不会被大量输入劝阻是有原因的——事实上,默认数字是 20,但列表可以扩展到 100 个输入,即为用户实现的选项。

感谢您的所有建设性答复,他们非常有帮助。

4

6 回答 6

2

这种负载当然是可以管理的,具体取决于您希望每个字段包含多少数据,或者更确切地说,取决于您确定每个字段可以包含的最大数据量。在 PHP 中,HTTP POST 请求正文的最大大小(即包含表单编码值的部分)由ini 值post_max_size确定。它的默认值为 2MB,但您可以在您的php.ini:

post_max_size = 10M # megabytes

或在您的.htaccess

php_value post_max_size 10M

设置时要小心,因为它不应超过系统上可用的 RAM 量。还要考虑您可能有多个用户请求此页面,如果他们每个人都为他们的请求分配了过多的 RAM,他们可能会挂起或崩溃您的服务器。

但是,请考虑这里的数学。即使您有 100 个字段,每个字段包含 20 个字节,也只有 2000 个字节,大约 2 KB。即使 1 Mbps 的上传速度非常慢,您的用户也可以每秒上传 128 KB。在这个速度下,100 个字段中的每一个都必须包含 1311 字节的数据,上传过程需要 1 秒。

在 Apache 上,默认超时为 300 秒,因此您的表单字段必须包含总计 37.5 MB 的大小,Apache 才会超时。您的主机(或您的服务器管理员)可能会稍微更改此设置,并且可能设置为更合理的值,例如 30 秒。但仍处于此限制,您将需要 3.75 MB 的数据,这可能比 100 个字段可以包含的数据多得多。

您也不应该担心客户端,因为即使是最吝啬的浏览器 (IE) 也将 POST 上传限制为 2 GB

基本上,我的观点是,即使连接速度很慢,HTTP 和您的服务器也能够处理这么多字段。我不确定 PHP 解析所有这些需要多长时间(您必须在服务器上对其进行基准测试),但我想影响可以忽略不计。

从用户的角度来看,我会说 100 个字段将是一个非常令人生畏的景象。如果可能的话,最好将您的表单分成更友好和更小的步骤,引导用户完成填写表单的过程。如果您不想将表单拆分为多个步骤,请至少考虑使用 javascript 保存表单的状态。请注意,在W3C 中推荐 5MB 的存储空间localStorage,因此这应该有足够的空间来存储您的所有字段。还要看看这个使用 cookie 的后备,但要厌倦。Cookie 的限制比localStorage. 我读过cookie 每个限制为 4KB,每个域 20 个 cookie. 您可能希望将存储的表单字段分配到多个 cookie 中,例如 10 个 cookie 中的 10 个表单字段。您可以使用以下方法在 cookie 中存储多个输入值encodeURIComponent()

var inputs = document.forms[0].getElementsByTagName('input')
    i      = 0,
    date   = new Date(),
    expires;

// Expires date (1 day in future)
date.setTime(date.getTime()+(24*60*60*1000));
expires = date.toGMTString();

for(var cookieNumber = 0; cookieNumber < 10; cookieNumber++) {
    var cookie = [];
    for(; i < (cookienumber * 10 + 10); i++) {
        cookie.append(encodeURIComponent(inputs[i].name) + '=' + encodeURIComponent(inputs[i].value));
    }

    document.cookie = 'savedForm' + cookieNumber + '=' + cookie.join('&') + '; expires =' + expires;
}

为确保在用户键入时保存所有内容,您可能需要更新存储的数据onchange,或者,如果您想要最多保存第二次,onkeyup.

另外,为了方便用户,当提交表单时,所有保存的 cookie 和localStorage表单字段数据都应该被清除,这样当他们再次访问表单时,所有字段都将为空并读取新数据输入。

于 2012-08-19T19:59:31.990 回答
2

将其分解为多个请求,通过多个步骤划分的表单不是更好吗?

从用户体验的角度来看,向用户显示 100 个字段听起来真的很糟糕。把它分成多个步骤怎么样?对用户来说不那么不堪重负,从服务器端的角度来看,您也可能更容易管理。

假设用户不小心关闭了窗口,失去了她的 Internet 连接或发生了其他一些问题,导致数据无法发送到服务器。如果在完成 100 个输入字段后发生这种情况,我可能会离开页面并且永远不会回来。

从性能的角度来看,我认为这不会有太大的不同,但我真的建议采取另一种方法。

于 2012-08-19T19:26:04.213 回答
1

毫无疑问,您已经控制了 UX 问题,或者您会在User Experience中提出这个问题。

从性能的角度来看,让我们考虑一些传递这些数据的策略。

1. HTTP POST (作为application/x-www-form-urlencoded传递的变量)

您提交的总大小很容易预测,但取决于表单中的内容。如果您只使用选择和复选框,或者使用整数或布尔值的隐藏变量,那么 100 个元素可能会变成 2KB 的数据。传递 2KB 的数据需要多长时间?不久。显然,文本字段会改变事物(也以您而非我们可以预测的方式),但可能不会显着。编码字符串var=Pack+my+box+with+five+dozen+liquor+jugs为 44 个字符。其中 100 个仍然会生成少于 5KB 的数据来上传。即使在模拟调制解调器速度(例如,28.8Kbps 或 2.8KB/s)下,也只需几秒钟。文件附件使我们进入下一个策略。

2. HTTP POST (作为multipart/form-data传递的变量)

如果您正在上传文件,您将使用它,并且可能不会用于其他用途。如果您打算使用表单上传 100 个 4MB JPEG 图像,那么我建议您通过实现基于 JavaScript 的后台上传器来简化事情。让用户在搜索他们的下一个文件时进行上传。除此之外,这种格式的总开销远远大于x-www-form-urlencoded,但与附加文件的大小相比,开销仍然可以忽略不计。

3. HTTP GET(作为 HTTP 请求的一部分传递的变量)

这基本上是一个标记在 URL 末尾的x-www-form-urlencoded字符串。见#1。

您应该考虑的另一个主要因素是处理此表格的速度。上传时间可能很小,但如果每个表单元素需要 3 秒的数据库访问和处理,那么 100 个项目会导致表单提交后等待 5 分钟。在不知道您的表单内容是什么或您真正想要在这里实现什么的情况下,除了说“考虑一下”之外,我无法就此事提供建议。

于 2012-08-19T19:59:19.063 回答
0

使用 POST 请求传递数据的标准方法,您可以将它们作为 $_POST 数组的一部分使用,这是非常好的。这种方法可以发送的数据量上限非常高。

如果你想要更灵活的东西,你可以先序列化数据,发送它,然后使用http_get_request_body()检索这些数据。但你不应该需要那个。表格非常适合您描述的场景。

于 2012-08-19T19:30:00.730 回答
0

100应该不是什么大问题。但是您可以使用 '[]' 对输入字段进行分组

因此:

Apple
<input type='checkbox' name='fruity[]' value='apple'>

Pear
<input type='checkbox' name='fruity[]' value='pear'>

Banana
<input type='checkbox' name='fruity[]' value='banana'>

如果你检查香蕉和梨,然后提交。结果是

$_POST = array( 
  0 => fruity => array ( 
    0 => 'pear', 
    1 => 'banana'
   ) 
 )
于 2012-08-19T19:30:22.487 回答
0

您可以使用通过 ajax 请求发布的 xml 变量,例如 MVC 概念。首先你设置了一个 xml 变量。其次,您将此 xml 变量作为文本发布。通过 ajax 请求查看 PHP 帖子,模型 php 将接收 xml 文本数据并使用 xml 查询将其分解以获得相同数量的变量。

于 2015-02-21T15:31:36.673 回答