我正在使用TCPDF动态创建PDF文档。生成这些PDF的一些查询包含超过1,000条记录,我的服务器超时查询(内部服务器错误)。我正在使用PHP和MySQL。
如何使用AJAX将大型MySQL查询解析为较小的块,缓存数据并重新组合结果,以防止服务器超时?
这是我目前的代码:
require_once('../../libraries/tcpdf/tcpdf.php');
$pdf = new TCPDF();
$prows = fetch_data($id);
$filename = '../../pdf_template.php';
foreach ($prows AS $row) {
$pdf->AddPage('P', 'Letter');
ob_start();
require($filename);
$html .= ob_get_contents();
ob_end_clean();
$pdf->writeHTML($html, true, false, true, false, '')
}
$pdf->Output('documents.pdf', 'D');
答案 0 :(得分:0)
如果绝对必须在每隔时间生成数据,那么您可以将查询分块为100行,将数据缓存在文件系统上(或者更好,在APC / WinCache / XCache / MemCache中)然后在最后的AJAX调用(Finalquery = true),加载缓存,生成PDF和清除缓存。
我假设您无法更改脚本的最长运行时间,例如<?php set_time_limit(0);
流程将如下:
wincache_ucache_add( $uniqueId . '.chunk' . $chunkNumber, $rows);
$rows = array_merge( wincache_ucache_get($uniqueId . '.chunk'. $chunkNumber1), wincache_ucache_get($uniqueId . '.chunk'. $chunkNumber2) );
wincache_ucache_clear();
请注意,您应该只是手动或通过抽象层或ORM中的功能来缓存查询结果。
答案 1 :(得分:0)
尝试像PEAR cache_lite这样的简单缓存。在缓慢或关闭期间,您可以创建一个实用程序来运行和缓存所需的所有记录。然后,当用户请求PDF时,您可以访问缓存数据,而无需访问数据库。此外,您可以只使用表上的timestamp字段并请求自缓存数据以来已更改的数据库记录,这将显着降低您必须实时从数据库中检索的当前记录数。
<?php
include 'Cache/Lite/Output.php';
$options = array(
'cacheDir' => '/tmp/cache/',
'lifeTime' => 3600,
'pearErrorMode' => CACHE_LITE_ERROR_DIE,
'automaticSerialization' => true
);
$cache = new Cache_Lite_Output($options);
if( $data_array = $cache->get('some_data_id') ) {
$prows = $data_array;
} else {
$prows = fetch_data($id);
$cache->save($prows);
}
print_r($prows);
?>