问题
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:
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
- Cookbook > Controllers > Controller actions
- Cookbook > Controllers > Request > Request and Response objects > CakeResponse > Dealing with content types
来源:https://stackoverflow.com/questions/43139141/echo-string-dont-work-properly