将大型可自定义项目列表传输到客户端

时间:2016-06-28 16:56:48

标签: php

我正在创建一个API,它从第三方组件中检索项目并以指定的XML / CSV / TEXT结构返回这些项目,管理员可以通过模板对其进行自定义。

问题:一个API请求可能很容易包含数百万个项目。因此,在内存方面不可能创建整个列表服务器端并将其发送给客户端。

相反,应该即时创建项目,并将结果立即发送到客户端,而不将它们存储在PHP的内存中。

这怎么可能?

示例模板:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>

<items>
    {items}
        <item no="{number}">{item}</item>
    {/items}
</items>

没有流媒体的当前代码示例。实际上并没有工作,但你应该知道:

echo preg_replace_callback('@{items}(.*){/items}@si', function (array $matches)
{
    return createItems($matches[1]);
}, $template);


function createItems($itemTemplate)
{
    $items = '';
    while (itemsExist()) {
        $items .= getItem($itemTemplate);
    }
}

我想,我应该停止缓冲var中的每个项目而不是直接回显它们?但是,如何保持XML的/ CSV / JSON结构完好无损或列表中的模板中的其他内容?

1 个答案:

答案 0 :(得分:1)

如果您达到了在服务器上生成的结果集太大而无法放入内存的程度,那么您应该考虑API的客户端如何处理这么大的内容结果也是如此。

我已经看到有两种模式可以解决这类问题:

1。分页

在API中使用分页来返回结果页面,就像在网页上一样。通常,这涉及向&#34;下一页&#34;提供URL。 API响应中结果集的结果。然后,客户端可以简单地迭代每个API响应,直到没有&#34;下一页&#34;响应中存在的URL,表示已到达结果集的末尾。

您的API响应如下所示:

{ 
   items: [ { }, { } ... ],
   next_page: "http://my.domain.com/results?page=2"
}

2。异步结果集生成

通过这种方法,您的客户将POST到您的API并立即获得令牌。

API将在后台执行整个响应的生成 - 通常使用消息队列系统,如RabbitMQSQS - 将结果保存到Web服务器上的文件中。请注意,这发生在HTTP请求之外,因此客户端在此过程中不会阻止Web服务器。

客户端定期轮询API,传递先前从API收到的令牌。最终,API将响应一些数据,以指示结果集已生成并准备下载。然后,API可以在其响应中包含结果集的内容,或者提供客户端可以从中下载结果集的URL。

还有第三种替代方案,但除非您计划为API使用者构建客户端库,否则我不会推荐它。您可以使用PHP的stream_ *函数来创建API将运行的流。这将允许您将数据推送到流上,并且您的客户端可以从流中读取数据,而不会消耗大量内存。但是,还有很多其他工作要做,特别是如果您需要客户端解析整个XML / JSON文档。

我会推荐分页。它易于推理,在API端实现并不困难,可重用并消除客户端和服务器端的内存消耗问题。