我有以下查看文件,当用户执行某些从系统中选择患者姓名的功能时,该查看文件将调用控制器actionListInvoices,后者依次执行一些检查并通过显示给用户的ajax响应html响应。这在localhost上运行良好,但是当我将其托管在实时服务器中时,出现以下错误:
An Error occurred while handling another error:
yii\web\HeadersAlreadySentException: Headers already sent in /home/stjamesh/public_html/backend/modules/finance/controllers/PaymentsController.php on line 152. in /home/stjamesh/public_html/vendor/yiisoft/yii2/web/Response.php:366
Stack trace:
#0 /home/stjamesh/public_html/vendor/yiisoft/yii2/web/Response.php(339): yii\web\Response->sendHeaders()
#1 /home/stjamesh/public_html/vendor/yiisoft/yii2/web/ErrorHandler.php(135): yii\web\Response->send()
#2 /home/stjamesh/public_html/vendor/yiisoft/yii2/base/ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\HeadersAlreadySentException))
#3 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\web\HeadersAlreadySentException))
#4 {main}
Previous exception:
yii\web\HeadersAlreadySentException: Headers already sent in /home/stjamesh/public_html/backend/modules/finance/controllers/PaymentsController.php on line 152. in /home/stjamesh/public_html/vendor/yiisoft/yii2/web/Response.php:366
Stack trace:
#0 /home/stjamesh/public_html/vendor/yiisoft/yii2/web/Response.php(339): yii\web\Response->sendHeaders()
#1 /home/stjamesh/public_html/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Response->send()
#2 /home/stjamesh/public_html/dashboard/index.php(17): yii\base\Application->run()
#3 {main}
建议针对此错误的解决方案,根据yii2的当前更新,应使用return而不是echo。
我的问题是我试图使用return,但是前端没有得到任何预期的东西。如何在动作控制器中使用return和html函数?
这是我的观点:
<?php
use yii\helpers\Html;
use kartik\widgets\ActiveForm;
use wbraganca\dynamicform\DynamicFormWidget;
use yii\helpers\ArrayHelper;
use kartik\datecontrol\DateControl;
use kartik\builder\Form;
/**
* @var yii\web\View $this
* @var app\models\Payments $model
*/
$this->title = 'Add Payment';
$this->params['breadcrumbs'][] = ['label' => 'Payments', 'url' => ['index']];
$this->params['breadcrumbs'][] = $this->title;
$js = '
jQuery(".dynamicform_wrapper").on("afterInsert", function(e, item) {
jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) {
jQuery(this).html("Payment: " + (index + 1))
});
jQuery(".dynamicform_wrapper .invoice-data").each(function(index) {
var new_index = index;
jQuery(this).attr("id", "payment-" + new_index + "-invoice")
});
});
jQuery(".dynamicform_wrapper").on("afterDelete", function(e) {
jQuery(".dynamicform_wrapper .panel-title-address").each(function(index) {
jQuery(this).html("Payment: " + (index + 1))
});
jQuery(".dynamicform_wrapper .invoice-data").each(function(index) {
var new_index = index;
jQuery(this).attr("id", "payment-" + new_index + "-invoice")
});
});
';
$this->registerJs($js);
$this->registerJs("
jQuery(function($){
$(document.body).on('change', '#payments-patient_id', function(){
var select_Id = $(this).attr('id');
var invoiceId = 'payment-invoice';
var id1 = $(this).val();
// alert(id1);
$.ajax({
type :'GET', cache : false, url : 'list-invoices', data: { patient_id : id1 }, success : function(response) {
alert(response);
$('#'+invoiceId).html(response);
}
});
return false;
});
});
");
?>
<div class="row">
<div class="payment-create">
<div class="payment-form">
<?php $form = ActiveForm::begin(['type' => ActiveForm::TYPE_VERTICAL]); ?>
<div class="padding-v-md">
<div class="line line-dashed"></div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-money"></i> Payments
<button type="button" class="pull-right add-item btn btn-success btn-xs"><i class="fa fa-plus"></i> Add Payment</button>
<div class="clearfix"></div>
</div>
<div class="panel-body container-items"><!-- widgetContainer -->
<div class="item panel panel-default"><!-- widgetBody -->
<div class="panel-heading">
<span class="panel-title-address">Make Payment</span>
<button type="button" class="pull-right remove-item btn btn-danger btn-xs"><i class="fa fa-minus"></i></button>
<div class="clearfix"></div>
</div>
<div class="panel-body">
<?php
echo Form::widget([
'model' => $model,
'form' => $form,
'columns' => 3,
'attributes' => [
'receipt_number' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Receipt Number...', 'disabled'=> true]],
'patient_id' => ['type' => Form::INPUT_WIDGET, 'widgetClass'=>'\kartik\widgets\Select2', 'options' => ['data'=>ArrayHelper::map(app\models\Patients::find()->all(), 'id', 'displayDetails'), 'options' => ['placeholder' => 'Select Patient...']]],
'payment_reference' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Payment Reference...']],
]
]);
echo Form::widget([
'model' => $model,
'form' => $form,
'columns' => 3,
'attributes' => [
'payment_date' => ['type' => Form::INPUT_WIDGET, 'widgetClass' => DateControl::classname(),'options' => ['type' => DateControl::FORMAT_DATETIME]],
'payment_method_id' => ['type' => Form::INPUT_WIDGET, 'widgetClass'=>'\kartik\widgets\Select2', 'options' => ['data'=>ArrayHelper::map(app\models\PaymentMethod::find()->all(), 'payment_method_id', 'method'), 'options' => ['placeholder' => 'Select a Payment Method...']]],
'amount' => ['type' => Form::INPUT_TEXT, 'options' => ['placeholder' => 'Enter Amount Paid...']],
]
]);
echo Form::widget([
'model' => $model,
'form' => $form,
'columns' => 1,
'attributes' => [
'notes' => ['type' => Form::INPUT_TEXTAREA, 'options' => ['placeholder' => 'Enter Notes...', 'maxlength' => 255]],
]
]);?>
<div class="invoice-data" id="payment-invoice"></div>
</div>
</div>
</div>
</div>
<div class="col-sm-offset-3 col-sm-9">
<?= Html::submitButton($model->isNewRecord ? 'Add Payment' : 'Update Payment', ['class' => 'btn btn-primary']) ?>
<?= Html::resetButton('Reset', ['class' => 'btn btn-default']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>
</div>
这是我的控制器:
<?php
namespace app\modules\finance\controllers;
use Yii;
use app\models\Payments;
use app\models\PaymentsSearch;
use app\models\FinancialTransactions;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* PaymentsController implements the CRUD actions for Payments model.
*/
class PaymentsController extends Controller
{
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
/**
* Lists all Payments models.
* @return mixed
*/
public function actionIndex()
{
$searchModel = new PaymentsSearch;
$dataProvider = $searchModel->search(Yii::$app->request->getQueryParams());
return $this->render('index', [
'dataProvider' => $dataProvider,
'searchModel' => $searchModel,
]);
}
/**
* Displays a single Payments model.
* @param integer $id
* @return mixed
*/
public function actionView($id)
{
$model = $this->findModel($id);
// $paymentInvoices = \app\models\PaymentInvoiceLink::find()
// ->where(['payment_id' => $id])
// ->all();
$paymentInvoices = \app\models\InvoiceLine::find()
->joinWith(['invoiceLinks il'])
->where(['il.payment_id' => $id])
->all();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->payment_id]);
} else {
return $this->render('view', [
'model' => $model,
'paymentInvoices' => $paymentInvoices,
]);
}
}
/**
* Creates a new Payments model.
* If creation is successful, the browser will be redirected to the 'view' page.
* @return mixed
*/
public function actionCreate()
{
$model = new Payments;
$modelTransactions = new FinancialTransactions;
$model->receipt_number = $model->receiptNumber;
if ($model->load(Yii::$app->request->post())) {
$transaction = Yii::$app->db->beginTransaction();
try {
$data = Yii::$app->request->post();
$period = \app\models\FinancialPeriod::find()
->where(['<=', 'date_from', date("Y-m-d")])
->andWhere(['>=', 'date_to', date("Y-m-d")])
->one();
$period_id = $period->period_id;
// create a transaction
$modelTransactions->debit_account_id = $modelTransactions->defaultDebitAccount($account_code = 'PAYRE');
$modelTransactions->credit_account_id = $modelTransactions->defaultCreditAccount($account_code = 'ARE');
$modelTransactions->amount = $data['Payments']['amount'];
$modelTransactions->notes = 'Payment received from patient';
$modelTransactions->period_id = $period_id;
$modelTransactions->branch_id = Yii::$app->user->identity->branch_id;
if (! ($flag = $modelTransactions->save())) {
$transaction->rollBack();
}
// create a payment
$model->created_by = Yii::$app->user->id;
$model->transaction_id = $modelTransactions->transaction_id;
$model->amount_unallocated = $modelTransactions->amount;
$model->branch_id = Yii::$app->user->identity->branch_id;
if (! ($flag = $model->save())) {
$transaction->rollBack();
}
if ($flag) {
$transaction->commit();
\app\models\Invoices::clearInvoices($model->patient_id);
return $this->redirect(['view', 'id' => $model->payment_id]);
} else {
$transaction->rollBack();
}
} catch (Exception $e) {
$transaction->rollBack();
}
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
public function actionTest()
{
$result = \app\models\Invoices::clearInvoices(2);
echo $result;
}
/**
* Displays an array of data model.
* @param integer $id
* @return mixed
*/
public function actionListInvoices($patient_id)
{
$invoices = \app\models\Invoices::find()->joinWith(['patientVisit pv'])->where(['pv.patient_id' => $patient_id])->andWhere(['or', ['invoices.status_id'=> 1], ['invoices.status_id'=> 4]])->all();
$count = \app\models\Invoices::find()->joinWith(['patientVisit pv'])->where(['pv.patient_id' => $patient_id])->andWhere(['or', ['invoices.status_id'=> 1], ['invoices.status_id'=> 4]])->count();
if ($count > 0) {
$total_amount = 0;
echo '<table class="table table-bordered table-inverse table-hover">
<thead class="thead-inverse">
<th>Invoice #</th>
<th>Invoice Date</th>
<th>Due Date</th>
<th>Amount</th>
<th>Amount Paid</th>
<th>Amount Due</th>
</thead>
<tbody>';
foreach($invoices as $invoice){
echo '<tr>
<td>'.$invoice->invoice_number.'</td>
<td>'.$invoice->date_created.'</td>
<td>'.$invoice->due_date.'</td>
<td>'.$invoice->invoiceAmount($invoice->invoice_id).'</td>
<td>'.$invoice->paidAmount($invoice->invoice_id).'</td>
<td>'.$invoice->amountDue($invoice->invoice_id).'</td>
</tr>';
$total_amount = $total_amount + $invoice->amountDue($invoice->invoice_id) - $invoice->amountUnallocated($invoice->patientVisit->patient_id);
}
echo '<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td><strong>Previous over-Payment</strong></td>
<td class="total">'.$invoice->amountUnallocated($invoice->patientVisit->patient_id).'</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td><strong>Total Due</strong></td>
<td class="total">'.$total_amount.'</td>
</tr>';
echo '</tbody></table>';
} else {
echo 'Patient has no pending invoice';
}
}
/**
* Updates an existing Payments model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id
* @return mixed
*/
public function actionUpdate($id)
{
$model = $this->findModel($id);
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->payment_id]);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
/**
* Deletes an existing Payments model.
* If deletion is successful, the browser will be redirected to the 'index' page.
* @param integer $id
* @return mixed
*/
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
/**
* Finds the Payments model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* @param integer $id
* @return Payments the loaded model
* @throws NotFoundHttpException if the model cannot be found
*/
protected function findModel($id)
{
if (($model = Payments::findOne($id)) !== null) {
return $model;
} else {
throw new NotFoundHttpException('The requested page does not exist.');
}
}
}
让我知道是否应该添加任何内容。
答案 0 :(得分:1)
查看您的代码并作为示例操作actionListInvoices
您可以用echo的内容构建一个字符串,并使用return代替echo
/**
* Displays an array of data model.
* @param integer $id
* @return mixed
*/
public function actionListInvoices($patient_id)
{
$invoices = \app\models\Invoices::find()->joinWith(['patientVisit pv'])->where(['pv.patient_id' => $patient_id])->andWhere(['or', ['invoices.status_id'=> 1], ['invoices.status_id'=> 4]])->all();
$count = \app\models\Invoices::find()->joinWith(['patientVisit pv'])->where(['pv.patient_id' => $patient_id])->andWhere(['or', ['invoices.status_id'=> 1], ['invoices.status_id'=> 4]])->count();
if ($count > 0) {
$total_amount = 0;
$myEcho = '<table class="table table-bordered table-inverse table-hover">
<thead class="thead-inverse">
<th>Invoice #</th>
<th>Invoice Date</th>
<th>Due Date</th>
<th>Amount</th>
<th>Amount Paid</th>
<th>Amount Due</th>
</thead>
<tbody>';
foreach($invoices as $invoice){
$myEcho .= '<tr>
<td>'.$invoice->invoice_number.'</td>
<td>'.$invoice->date_created.'</td>
<td>'.$invoice->due_date.'</td>
<td>'.$invoice->invoiceAmount($invoice->invoice_id).'</td>
<td>'.$invoice->paidAmount($invoice->invoice_id).'</td>
<td>'.$invoice->amountDue($invoice->invoice_id).'</td>
</tr>';
$total_amount = $total_amount + $invoice->amountDue($invoice->invoice_id) - $invoice->amountUnallocated($invoice->patientVisit->patient_id);
}
$myEcho .= '<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td><strong>Previous over-Payment</strong></td>
<td class="total">'.$invoice->amountUnallocated($invoice->patientVisit->patient_id).'</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td><strong>Total Due</strong></td>
<td class="total">'.$total_amount.'</td>
</tr>';
$myEcho .= '</tbody></table>';
} else {
$myEcho ='Patient has no pending invoice';
}
return $myEcho;
}
并(作为建议)在MVC模式中,应将输出代码放置在视图中,而不是在控制器/动作内部。(在控制器/动作中,您应检索数据并调用传递数据的render函数)