I have problem with setting headers in ZF2. My code looks like this:
public function xmlAction()
{
$headers = new \Zend\Http\Headers();
$headers->clearHeaders();
$headers->addHeaderLine('Content-type', 'application/xml');
echo $file; // xml file content
exit;
}
But headers are still text/html. I can set the proper header with:
header("Content-type: application/xml");
but I would like to do it with Zend Framework. Why code above doesn't work?
What you are doing is setting headers in a ZF2 Response object, but this response is later on never used. You are echoing a file and then exiting, so there is no chance for ZF2 to send the response (with its headers).
You have to use the response to send the file, which you can do like this:
public function xmlAction()
{
$response = $this->getResponse();
$response->getHeaders()->addHeaderLine('Content-Type', 'application/xml');
$response->setContent($file);
return $response;
}
The idea of returning the response from a controller method is called "short circuiting" and is explained in the manual
Try -
public function xmlAction()
{
$this->getResponse()->getHeaders()->addHeaders(array('Content-type' => 'application/xml'));
echo $file; // xml file content
exit;
}
Related
I have the following route:
Route::get('echo',function (Request $req) {
return response()->stream(function () use ($req) {
echo json_encode($req->all());
}, 200, [
'Content-Type' => 'application/json'
]);
})->name('echo');
For the sake of simplicity lets assume it's a simple echo response. In reality it's a very large file. The outcome in either case is the same.
Now I want to test this route to see whether I indeed can see that json content so I've tried this:
public function testBasicTest()
{
$response = $this->get(route('echo', [
"content"=>"some content"
]));
$response->assertSeeText("some content"); //Doesn't work
$response->assertJson( [
"content"=>"some content"
]); //Neither does this
}
I've inspected it a bit further and it appears to be because (a) the response is wrapped around a TestResponse (b) the response content is never streamed and (c) even if the response content were to be forcibly streamed via $response->baseResponse->sendContent() the actual content is echoed and not actually captured by the TestResponse
In addition calling $response->getContent() does not work because it seems to directly call the StreamedResponse::getContent() which is hard-coded to return false.
I have managed to have some limited success using:
ob_start();
$response->sendContent();
$result = ob_get_clean();
however this looks like a very sloppy thing to do in a unit test.
Has anyone else encountered this before? Is it possible to test the contents of a streamed response?
This is not a good solution, more of a hack, but if anyone else encounters this issue here's what you can do:
public function testBasicTest()
{
$response = $this->get(route('echo', [
"content"=>"some content"
]));
if ($response->baseResponse instanceof StreamedResponse) {
ob_start();
$response->sendContent();
$content = ob_get_clean();
$response = new TestResponse(
new Response($content,
$response->baseResponse->getStatusCode(),
$response->baseResponse->headers->all()
)
);
}
$response->assertSee("some content"); //Works
}
A bit late to the party but it may help someone else.
In Laravel you can do $response->streamedContent() when handling a StreamedResponse (since 5.8 I believe).
Even tho my debugger told me the streamed content of my response was null I still got the data out of it.
In my case it was CSV so in my functional tests I've done :
$res = $this->post('api/v1/entity/export', $payload, $header);
$res->assertStatus(200);
$res->assertHeader('Content-Disposition', 'attachment; filename=entity.csv');
$reader = Reader::createFromString($res->streamedContent());
// tests...
I used LeagueCSV (bc it was CSV, obviously) but I'm sure you can do the same with Json or other.
Laravel doc for TestResponse
I'd like to generate a JavaScript file for JSONP data exchange.
All fine, but I need / want to set the header as :
header("Content-Type: text/javascript");
or
header("Content-Type: application/javascript");
Is this possible in a response from a controller in Laravel 4, or do I need to create a view and set the header with PHP?
I'd like to output something like:
var obj = JSON.parse('{"item1":"value1","item2":"value2"}');
// then do whatever with the object
$('#somediv').html(obj.item1);
Thanks for your help in advance
Okay, looks like I have to answer my question myself :-). Thanks to #terrylow for trying though.
Here is the way to change the header of my response using my function in my controller
public function javascriptResponse(){
$statusCode = 200;
$content = "var obj = JSON.parse('{\"item1\":\"value1\",\"item2\":\"value2\",\"some\":\"whoaevaNew\"}');";
$response = Response::make($content, $statusCode);
$response->header('Content-Type', 'application/javascript');
return $response;
}
variable content can also be filled with a view:
$content = View::make('tools/jsonp_resonse'); // also possible with view
Hope that will help someone...
you can use this method provided by laravel
return Response::jsonp($callback, $data,$status, $header);
I'm using PHP 5.3, and trying to develop a simple web service that gets some parameters with POST method and has a response.
function start(){
getAndValidateParams();
global $response;
echo json_encode($response);
}
function getAndValidateParams(){
// token (mandatory)
if(isset($_POST[PARAM_TOKEN])){
echo 'got your token';
}else{
$response[ERROR_CODE] = ERR2_INVALID_TOKEN;
$response[DESCRIPTION] = CODE2_DESC;
}
}
I'm trying to test that with Postman:
The problems:
1. About the Xdebug HTML I saw the following question, If I turn the var_dump off, will it disable usage of var_dump() inside my php code? (I want to be able use it for debugging but not seeing that in the response).
2.Also I have a problem to pass the parameter 'token', I don't see it in getAndValidateParams().
Any help will be appreciated.
I have used your function to just get insight in this and for tesing you can use also there is Advanced REST client in chrome similar to postMAN that you are using --
use the below lines to debug this --
function start(){
$response = getAndValidateParams();
return json_encode($response);
}
// calling function ends here
// statrt another function that is being called
function getAndValidateParams(){
// token (mandatory)
// print_r($_POST);die; // just for debug purpose
if(isset($_POST[PARAM_TOKEN])){
$response[ERROR_CODE] = 0;
$response[DESCRIPTION] = "Success";
$response[DEtail] = $yourdetailarr; // array of data that you want to retuen
}else{
$response[ERROR_CODE] = ERR2_INVALID_TOKEN;
$response[DESCRIPTION] = CODE2_DESC;
}
return $response;
}
/// ends here
check the response here by calling start function .
I'm using Zend Framework 1.x for my project. I want to create a Web service return only JSON string for the caller function. I tried to use Zend_Controller_Action and applied those ways:
1.
$this->getResponse()
->setHeader('Content-type', 'text/plain')
->setBody(json_encode($arrResult));
2.
$this->_helper->getHelper('contextSwitch')
->addActionContext('nctpaymenthandler', 'json')
->initContext();
3.
header('Content-type: application/json');
4.
$this->_response->setHeader('Content-type', 'application/json');
5.
echo Zend_Json::encode($arrResult);
exit;
6.
return json_encode($arrResult);
7.
$this->view->_response = $arrResult;
But when I used cURL to get result, it returned with JSON string surrounded by some HTML tags. Then I tried to user Zend_Rest_Controller with the options above. It still did not success.
P.S.: Most of those ways above are from the question which had been asked on Stack Overflow.
I Like this way!
//encode your data into JSON and send the response
$this->_helper->json($myArrayofData);
//nothing else will get executed after the line above
You need to disable the layout and view rendering.
Explicit disable layout and view renderer:
public function getJsonResponseAction()
{
$this->getHelper('Layout')
->disableLayout();
$this->getHelper('ViewRenderer')
->setNoRender();
$this->getResponse()
->setHeader('Content-Type', 'application/json');
// should the content type should be UTF-8?
// $this->getResponse()
// ->setHeader('Content-Type', 'application/json; charset=UTF-8');
// ECHO JSON HERE
return;
}
If your using the json controller action helper you need to add a json context to the action. In this case the json helper will disable the layout and view renderer for you.
public function init()
{
$this->_helper->contextSwitch()
->addActionContext('getJsonResponse', array('json'))
->initContext();
}
public function getJsonResponseAction()
{
$jsonData = ''; // your json response
return $this->_helper->json->sendJson($jsonData);
}
Your code would need to disable the layout as well in order to stop the content being wrapped with the standard page template. But a much easier approach would just be:
$this->getHelper('json')->sendJson($arrResult);
the JSON helper will encode your variable as JSON, set the appropriate headers and disable the layout and view script for you.
It is much easier.
public function init()
{
parent::init();
$this->_helper->contextSwitch()
->addActionContext('foo', 'json')
->initContext('json');
}
public function fooAction()
{
$this->view->foo = 'bar';
}
I've got problems with PHP PEAR and HTTP PUT. I want to create a HTTP PUT request and attach a file to it and send it to a REST service. Here's my current code:
require_once ('includes/HTTP_Request/Request.php');
$url = 'http://myurl.com/';
$req =& new HTTP_Request();
$req->setMethod(HTTP_REQUEST_METHOD_PUT);
$req->setURL($url);
$req->addHeader('Content-type', 'multipart/form-data');
$tmp_file = 'temp.rdf';
$result = $req->addFile('metadata', $tmp_file, 'text/xml');
if (PEAR::isError($result))
{
echo $result->getMessage();
}
$response = $req->sendRequest();
if (PEAR::isError($response)) {
echo $response->getMessage();
} else {
echo $req->getResponseBody();
}
This code should work correctly, but obviously is doesn't. I always get the respond by the REST repository that the header doesn't contain multipart/form-data.
Does anyone know what I can do to get the code to work? Thanks in anticipation!
Use setBody( string $body) instead of addFile.
Sets the request body (for POST, PUT
and similar requests)