2

I'm using Symfony2 and I have some code to execute. It performs some database backup type work. That is not important for this question.

What I want is when I press a button it'll perform the code and get back to the main view. Don't load / reload any page. But controller is always expecting a response.

The controller must return a response (null given). Did you forget to add a return statement somewhere in your controller?

So I tried to fake it with null

Button code like

<li id="menu"><a href="{{ path('backup_label') }}"><span class="icon-align-justify"></span> Backup</a></li>

And response codes that I tried

return $this->render(
        null,
        array('status' => 'ok')

    );

OR

return $this->render(
        '',
        array('status' => 'ok')

    );

OR

return new Response('<html><body></body></html>')

OR

return new Response()

These are either returning error or blank page.

What's the way to execute some php code without getting a new response? Call a function,execute and keep the same view without any loading, Simple.

I can do it using ajax. But I'm hoping that if it's possible without ajax.

AtanuCSE
  • 8,832
  • 14
  • 74
  • 112
  • It doesn't makes sense,logically if you are hitting some controller action then there should be some response therefore its mandatory for controller to generate some response either your request completed or failed there should be some check regarding your request – M Khalid Junaid Feb 02 '15 at 07:51
  • @MKhalidJunaid all I want is not to give a page load/reload. My code will download a zip. That's it. It's that simple. But symfony controller response is forcing me to reload/load. Execute a piece of code without page loading. and without ajax. now if there should be a response , what should it be that I don't know and that is what this question is about. – AtanuCSE Feb 02 '15 at 08:10
  • Look at this part in official documentation: http://symfony.com/doc/current/components/http_foundation/introduction.html#serving-files. You don't need (although you can) to set headers manually - you just need to use appropriate response. – Alex Feb 02 '15 at 09:39
  • @AtanuCSE Alex is right you have do your stuff for generation of zip data and return the response with correct header in that way your page won't reload instead it just downloads the content return from your controller i.e zip file – M Khalid Junaid Feb 02 '15 at 09:44

2 Answers2

4

Downloading a zip file is a HTTP response nonetheless. You can accomplish what you are trying to do within the Symfony HTTP foundation, and you also should never circumvent that standard flow since it might break things. For starters, exiting in the controller will prevent the kernel.terminate and others events to trigger, so listeners will not be called, which might break stuff you did not know about.

Instead use a response object:

$response = new Response();
$response->headers->set('Content-Description', 'File Transfer');
$response->headers->set('Content-Type', 'application/octet-stream');
$response->headers->set('Content-Disposition', 'attachment; filename=' . basename($zipfname));
$response->setContent(file_get_contents($zipfname));
return $response;

If your zip file is large, the StreamedResponse class might be a better alternative since this way it doesn't load the file contents in memory:

$response = new StreamedResponse(function() use ($zipfname) {
    readfile($zipfname);
});
// set headers
return $response;
Gerry
  • 6,012
  • 21
  • 33
  • Exactly this is what I wanted. My answer was just what worked for me right now in urgency. Thanks for giving a more perfect answer. accepting it :) – AtanuCSE Feb 02 '15 at 16:47
2

HTTP has no proper concept of a "current" view because it's stateless. It's a request / response protocol, so any action the user requests of the web server must be answered with a response of some kind.

That said, appearing to stay on the same page is perfectly valid. You can either use ajax or respond by sending the same content / response as you did before the user pressed the button. You could use HTTP_REFERER, but that's not 100% reliable so you may want to use another method. Alternatively, if you know for sure which page you want to redirect the user to, simply do your db backup and forward the request to the right action.

Community
  • 1
  • 1
Mathew
  • 8,203
  • 6
  • 37
  • 59
  • My request to server doesn't require anywhere to redirect, it should remain in the same page. So yes I can produce a response to redirect to same page. but this will cause a page reload. I want to know if I can avoid this page load? and without ajax? `forward` will cause page reload. – AtanuCSE Feb 02 '15 at 08:34
  • It depends on what you want to do. If you're triggering a file download, then your response is the file itself and the browser will keep the user on the current page. If are doing something else, you need to ensure that the client's request doesn't effect the current response (page). The easiest way to do that is probably ajax – Mathew Feb 02 '15 at 10:18