php - 如何在 foreach 循环中使用输出缓冲区?
问题描述
我正在构建一个简单的类,它可以通过模板包含和我在输出缓冲区中提取的数据数组的组合为我的电子邮件正文生成 html。
问题是,当我在循环内使用输出缓冲区运行该方法时(根据用户信息创建电子邮件),我收到以下错误:
ob_end_clean():删除缓冲区失败。没有要删除的缓冲区...无法修改标头信息-标头已由...发送
我必须更改什么才能使其既适用于单个电子邮件又适用于循环内?
电子邮件类
<?php
class Email {
protected $_html;
protected $_data;
public function __construct( array $email_data = [] ) {
$this->_data = $email_data;
$this->generate_html();
}
protected function generate_html() {
$template_path = 'path/to/email-template.php';
ob_start();
extract( $this->_data );
include $template_path;
$this->_html = ob_get_contents();
ob_end_clean();
}
public send( $to = [] ) {
mail( $to, 'Test email', $this->_html, ['Content-Type: text/html; charset=UTF-8'] );
}
}
?>
测试我的代码:
<?php
function send_test_email( $id, $to ) {
$email_data = [
'id' => $id,
'name' => 'Joe',
'price' => '30.00'
];
$email = new Email( $email_data );
$email->send( $to );
}
// Works
send_test_email( 122, 'joe@example.com' );
// Does not work
// ob_end_clean(): failed to delete buffer. No buffer to delete in
// Cannot modify header information - headers already sent by ...
foreach ( $users as $user ) {
send_test_email( $user->id, $user->email );
}
?>
解决方案
让我们看看输出缓冲区是如何工作的:
// Works
send_test_email( 122, 'joe@example.com' );
/*
When you have executed send_test_email() above the method generate_html() is
executed and ob_start and ob_end_clean() is executed. This means that the output
buffer is initiated and stopped with ob_end_clean().
When output buffer is ended it is sent to the client (browser).
*/
//If you do the same again...
send_test_email( 122, 'joe@example.com' );
/*
...this won't work because output buffer is sent to the browser. After this is done
you are not able to modify header information. Because you cannot modify header
information you can not start a new output buffer either.
That is why you get the error below:
ob_end_clean(): failed to delete buffer. No buffer to delete in
Cannot modify header information - headers already sent by ...
*/
为了解决这个问题,我会尝试这样的事情:
移出ob_start()
和移出ob_end_clean()
类并将它们从方法中删除generate_html()
protected function generate_html() {
$template_path = 'path/to/email-template.php';
extract( $this->_data );
include $template_path;
$this->_html = ob_get_contents();
}
测试你的代码:
ob_start();
send_test_email( 122, 'joe@example.com' );
foreach ( $users as $user ) {
send_test_email( $user->id, $user->email );
}
ob_end_clean();
更新 您可以在不弄乱输出缓冲区的情况下解决这个问题,例如:
protected function generate_html() {
$template_path = 'path/to/email-template.php';
extract( $this->_data );
//requires the template file to have a return to able to store the
//content in a variable
//
//Look at $foo = include 'return.php';
//at https://www.php.net/manual/en/function.include.php
$this->_html = include $template_path;
}
推荐阅读
- c++ - 不想重复猜谜游戏中创建的数字
- pine-script - Pine Script 当前价格指标
- python - 如何使用Python消除微分方程中的任意常数
- mysql - 查询mysql到laravel
- javascript - 自动点击 javascript
- excel - 为什么 Application.Run 是 Excel 库的成员,而 CallByName 通常适用于所有 VBA?
- reactjs - Saga 中的 yield axios.get() 调用将路径名更改为默认位置“/”
- python - tkinter 中不同形状的窗口
- java - 检查是否可以使用递归将一个字符串转换为另一个字符串
- jquery - DataTable row() 始终未定义,无法从数据库中检索数据