18

I am trying to submit a comment on a guestbook application based on the Yii 2 Framework. On localhost on my PC works everything fine, but on the shared hosting when I want to submit a comment in View, I get this error.

Here is the error:

An error occurred while handling another error:
    exception 'yii\web\HeadersAlreadySentException' with message 'Headers already sent in /home/mahdikas/public_html/guestbook/controllers/PostController.php on line 117.' in /home/mahdikas/public_html/guestbook/vendor/yiisoft/yii2/web/Response.php:366
    Stack trace:
    #0 /home/mahdikas/public_html/guestbook/vendor/yiisoft/yii2/web/Response.php(339): yii\web\Response->sendHeaders()
    #1 /home/mahdikas/public_html/guestbook/vendor/yiisoft/yii2/web/ErrorHandler.php(135): yii\web\Response->send()
    #2 /home/mahdikas/public_html/guestbook/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:
    exception 'yii\web\HeadersAlreadySentException' with message 'Headers already sent in /home/mahdikas/public_html/guestbook/controllers/PostController.php on line 117.' in /home/mahdikas/public_html/guestbook/vendor/yiisoft/yii2/web/Response.php:366
    Stack trace:
    #0 /home/mahdikas/public_html/guestbook/vendor/yiisoft/yii2/web/Response.php(339): yii\web\Response->sendHeaders()
    #1 /home/mahdikas/public_html/guestbook/vendor/yiisoft/yii2/base/Application.php(392): yii\web\Response->send()
    #2 /home/mahdikas/public_html/guestbook/web/index.php(12): yii\base\Application->run()
    #3 {main}

In the postController I have this code:

public function actionAdd_comment()
{
  //print_r($_POST);
  $model = new \app\models\Comments;
  if ($model->load(Yii::$app->request->post()) && $model->validate()) {
    $model->comment_date = date('Y-m-d H:i:s');
    if ($model->save()) {
      echo 'Thanks for your comment.';
    } else {
      echo 'Failed!';
    }
  }
}

which line 117 in the error is:

echo 'Thanks for your comment.';

How can I solve this problem?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mahdi Kashani
  • 213
  • 1
  • 2
  • 6

2 Answers2

34

Since Yii 2.0.14 you cannot echo in a controller. A response must be returned:

public function actionAdd_comment() {
    $model = new \app\models\Comments();
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        $model->comment_date = date('Y-m-d H:i:s');
        if ($model->save()) {
            return 'Thanks for your comment.';
        } else {
            return 'Failed!';
        }
    }
}

You may also call exit at the end of your method to prevent further processing or wrap your code with ob_start() and ob_get_clean(), if you're not able to avoid echo.

public function actionAdd_comment() {
    $model = new \app\models\Comments();
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        $this->someMagicWithEcho();
        exit;
    }
}

or

public function actionAdd_comment() {
    $model = new \app\models\Comments();
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        ob_start();
        $this->someMagicWithEcho();
        return ob_get_clean();
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rob006
  • 21,383
  • 5
  • 53
  • 74
  • Does this mean that you have to include exit in all functions? – Paul Wakhungu Jul 19 '18 at 19:40
  • It means that you should return response instead of echoing it. `exit` is only a solution when you're not able to avoid echo - it should be pretty rare situation. – rob006 Jul 19 '18 at 19:49
  • I don't have an echo on any of my controllers, but I have also just encountered the error. – Paul Wakhungu Jul 19 '18 at 19:51
  • You definitely have have some output somewhere - it is either `echo` or some space before/after opening/closing PHP tag. – rob006 Jul 19 '18 at 19:56
  • Thank you!! For some odd reason i had 3 conditions with an echo json at the end, and had no issues, then added a fourth and ran into this.. i added ``exit;`` at the end of each condition, and it was all good – Peter Sep 21 '22 at 16:47
2

Although I accept rob006's solution as correct, I have encountered a situation where there was no echo in the controller, but I also got the error. After going through several sites looking for a solution, I discovered an alternative.

You can check the php.ini file and ensure the output buffer is enabled. If not, you can enable it by adding this line in php.ini if it does not exist:

output_buffering = on

And turn it off for just the script - the script where it is not required by either...

  1. calling ob_end_flush(), or
  2. calling ob_end_clean()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paul Wakhungu
  • 322
  • 2
  • 18