php - Smarty 时不时地返回一个空结果
问题描述
我在使用 Smarty 时遇到了一个奇怪的问题。我正在通过模板生成电子邮件的正文。大多数时候它按预期工作,但有时返回的数据是空的。但是,我在日志中没有看到任何错误,也没有发现任何异常。就好像模板是空的。
这是我用来获取电子邮件正文的一段代码:
// $data is an array with template's data
// $tpl is the template's path
$s = new Smarty();
$s->assignArray( $data );
try {
$body = $s->fetch( $tpl );
} catch ( \Exception $e ) {
Debug::Log( $e->getMessage() );
}
// Sometimes $body is empty, but no exception is thrown.
我检查了模板没有错误,毕竟它在大多数情况下都有效。
当 $body 为空时,我还保存了 $data 内容并手动运行代码以获取 $body 内容,但它有效,所以我认为问题与模板变量无关。
我做的另一个测试是尝试处理模板最多 5 次,在两次尝试之间休眠一秒钟,但结果总是空的。
模板的缓存路径是可写的。
我正在使用 PHP 5.6.40、Smarty 3.1.21 和 Apache2。
你能帮我调试一下这个问题吗?
更新
我已经能够重现该问题。每当 PHP 检测到客户端关闭连接后调用 fetch 方法时,Smarty 总是返回一个空结果。例如,使用以下代码:
ignore_user_abort(1); // Continue running even if the connection is closed
set_time_limit(180); // 3 minutes
$s = new Smarty();
$s->assignArray( $data );
// Keep writing data untill PHP realises that connection was closed
while( 1 ) {
if(connection_status() != CONNECTION_NORMAL || connection_aborted( ) ) {
break;
}
echo "123456789";
}
$body = $s->fetch( $tpl );
if ( '' == $body ) {
throw new Exception("Result is empty");
}
die('Code never reaches this point');
如果我调用上面的脚本并立即关闭连接,则 fetch 方法的结果始终为空。
但是,如果 PHP 没有检测到连接已关闭,即使确实如此,那么 fetch 的结果也不为空。
ignore_user_abort(1); // Continue running even if the connection is closed
set_time_limit(180); // 3 minutes
$s = new Smarty();
$s->assignArray( $data );
// Sleep to make sure the connection was closed
// PHP do not realise the connection is closed untill it tries to write something
sleep( 60);
$body = $s->fetch( $tpl );
if ( '' == $body ) {
throw new Exception("Result is empty");
}
echo "Now the result is not empty";
这是我用来调用上述脚本的代码:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://myhost/test.php');
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec($ch);
curl_close($ch);
echo "all done";
这似乎与这个问题有关:PHP ob_get_contents "sometimes" return empty when it should not?
我的脚本做了很多事情,所以需要很长时间才能完成。一些用户在脚本完成之前关闭浏览器,这就是 Smarty 返回空结果的时候,因为它经常使用 ob_start。
最好的祝愿,
解决方案
毫无例外地空白页面似乎是 smarty 做所有事情的方式。
我不熟悉python,但是,我怀疑只会抛出异常。不是通知。您可以尝试在代码末尾检查抛出的通知或其他警告,无论它是在 python 中调用的。
它可能仍然是文件夹权限,您是否还检查过 templates_c 目录是否存在,并且有操作?或任何不带 $ 的 {var.name}。
它可以是任何东西,smarty 从不抛出异常,它只是使页面空白。
如果它仍然没有帮助,请创建一个基本的过于简化的模板,然后尝试一段时间,看看它是否仍然会发生。如果是这样,那是您的模板中的错误。
推荐阅读
- mysql - Maria DB - 为 SQL 事件中的每一行执行存储过程
- python - How do I open an FTP directory so that I can use it the same way I could a normal directory?
- mongodb - Docker compose-Spring 引导服务未连接到 mongodb
- spring - java.io.FileNotFoundException:
/ (没有这样的文件或目录) - java - 将列表转换为数组并返回
- go - 在golang中将对象从一个包传递到下一个包
- magento2 - 在客户地址中添加新的自定义地址类型(付款人),例如 magento2 中的计费和运输
- r - R如何在group_by之后仅替换列中的连续重复值
- javascript - 使用 Vanilla JS 的 Ionic Routig
- java - 为什么 java.ci.totalTime 比 sun.rt.safepointTime (JVM PerfCounters) 大?