1

Working with an MVC framework and the controller renders the page in the destructor. I am downloading a file through php, so at the end of the action the script should end.

How to end the script without calling the destructor?

Is there a better solution?

exit and die call the destructor.

6
  • It's a custom framework. Commented Jul 2, 2012 at 22:56
  • 1
    I find it strange that the page will be rendered in the destructor method. Why not in a render method which is called by the framework? Am I missing something? Commented Jul 2, 2012 at 22:57
  • 1
    Can you extend that controller and override it's destructor with an empty destructor? This should be the most elegant way and it keeps in line with the frameworks philosophy (twisted as it is). It does need a bit of URL changing if the framework has Controller/Action/Parameters routes. Commented Jul 2, 2012 at 22:57
  • @ThomasClayson it's a twisted view of a semi event-drive architecture. Building a render function is the same as registering it to the render event. That kind of implicit-to-the-max philosophies. Commented Jul 2, 2012 at 22:59
  • If I am understanding correctly, you want to halt the script. If memory serves exit() will halt the function its within, while allowing the rest of the site/service to render gracefully in a matter of speaking, die will halt everything. If your downloading a file through PHP though the script should end with the download. Unless you have it checking somehow through a loop of some sort to see if its complete, in that case I would use break to kill the loop, all in all Not sure whats going on and how so I can only speculate. Commented Jul 2, 2012 at 23:00

3 Answers 3

3

See this answer. Try creating a destructor in the class that downloads the file that checks if a file was indeed sent to the browser, and if so, call exit() in that destructor.

Sign up to request clarification or add additional context in comments.

1 Comment

Did you take the order of destructor calls into account? If you create $obj1 and $obj2, will destructors be called as dest2 and dest1? Or is the order dictated by when the object gets out of scope?
2

As David said: you'll need to call exit() inside a destructor to stop it.

If however you just want to halt the visual output caused by these destructors but not any other side-effects (file closing, database connection closing) they might do, then it's best to just kill the further output but leave the destructors alone. Which in my opinion would be the route to take since destructors tend to be there for one important reason: cleaning up.

you can do that by manipulating buffered output:

<?php
class Tester{
   public function devNull($string){
       return "";
   }

   public function runAndBreak(){
        print "run" . PHP_EOL;

        // if any output buffer is working, flush it and close it
        if(ob_get_level()) ob_end_flush();

        // redirect new buffer to our devNull
        ob_start(array($this,'devNull'));
        exit();
        print "still running";

   }

   function __destruct(){
        print "destructor" . PHP_EOL;
   }

}

$t = new Tester();
$t->runAndBreak();

this will only print run and not what's in the destructor. It's done by giving your own callback routine to ob_start that handles and then returns the output. In our case here we simply discard it by returning an empty string.

Comments

0

This will certainly stop your script but be careful, if you run such a server where one process serves several PHP requests those will stop as well:

$pid = getmypid();
exec("kill $pid");
exec("TSKILL $pid");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.