Echo String dont work properly

2019-08-19 03:01发布

I'm using cakePHP 2.x. I'm trying to render a view with an empty layout. The view should contain only a string returned from the action controller with no html code. Here is the code:

 public function checkout(){

     $ref =null;$act=null;$par=null;

     $this->layout = false;
     //$this->render(false);

     //$priceCTP = $this->Session->read('priceCTP');;
     $priceCTP = $this->getPrice();
     //var_dump(session_save_path());

     if (isset($this->params['url']['Reference'])) {
         $ref = $this->params['url']['Reference'];
     }
     if (isset($this->params['url']['Action'])) {
         $act = $this->params['url']['Action'];
     }
     if (isset($this->params['url']['Param'])) {
         $par = $this->params['url']['Param'];//$_GET['Param'];//this->request->params['named']
     }
     switch ($act) {
         case "DETAIL":// accéder à la base et récuperer le montant
             echo "Reference=".$ref."&Action=".$act."&Reponse=".$priceCTP;
             break;
         case "ERREUR": // accéder à la base et mettre à jour l’état de la transaction
             echo "Reference=".$ref. "&Action=".$act. "&Reponse=OK";
             break;
         case "ACCORD": // accéder à la base, enregistrer le numéro d’autorisation (dans param)
             echo "Reference=".$ref. "&Action=".$act. "&Reponse=OK";
             break;
         case "REFUS":  // accéder à la base et mettre à jour l’état de la transaction
             echo "Reference=".$ref. "&Action=".$act. "&Reponse=OK";
             break;
         case "ANNULATION":  // accéder à la base et mettre à jour l’état de la transaction
             echo "Reference=".$ref. "&Action=".$act. "&Reponse=OK";
             break;
     }
}

the result on this url(http://mydomain/orders/checkout?

Reference=123&Action=DETAIL&Param=)

"Reference=123&Action=DETAIL&Repon"
rather than 
"Reference=123&Action=DETAIL&Reponse=121,630" (works fine on localhost).

1条回答
ら.Afraid
2楼-- · 2019-08-19 03:26

Do not echo data from controllers

As mentioned in the comments, controller actions are not supposed to echo data, even though it might work in some, maybe even most situations. The correct way of outputting data is by using (data) views, by configuring and return the response object, or even returning a string (which however isn't forward compatible with future versions of CakePHP).

Echoing data can lead to all kinds of problems, from the data not being recognized in the test environment, to headers not being able to be sent, and even data being cut off, which is what you are experiencing. The latter can for example happen when the size sent in the Content-Length header doesn't match the actual size of the data being sent, this often happens in situations where the content is being gzipped.

Content-Length mismatch is likely the cause

If you've run into the length mismatch for gzipped responses problem, then you have to figure out where compression is being involved (on server level (for example mod_deflate), on PHP extension level (for example zlib), on PHP code level (for example CakeResponse::compress())), and why it doesn't set the proper length accordingly.

Proper controller action logic

That being said, just pass the required data to the view, and build and echo the reponse data from there. Given that you don't want to respond with HTML, you probably also want to set the response type accordingly:

public function checkout()
{
    $this->response->type('text'); // = text/plain

    // ...

    $this->set(compact(array('priceCTP', 'ref', 'act', 'par')));
}

As mentioned, another option would be to return a proper response object:

public function checkout()
{
    $this->response->type('text');

    // ...

    $body = "Reference=" . $ref . "&Action=" . $act . "&Reponse=";
    switch ($act) {
        case "DETAIL":
            $body .= $priceCTP;
            break;

        case "ERREUR":
        case "ACCORD":
        case "REFUS":
        case "ANNULATION": 
            $body .= "OK";
            break;

        // ...
    }

    // ...

    $this->response->body($body);
    return $this->response;
}

ps. do you really want to respond with a key in french? Reponse maybe should be Response.

pps. given that you respond with a query string, you may want/need to URL encode the values accordingly.

See also

查看更多
登录 后发表回答