SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 36
  1. #1
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Sending response to user and continue execution

    I need to write a PHP script that takes a lot of time for execution. I need to give response to user by executing the script (first few lines) required for output and continue execution of the remaining script.

    Is there anyway I can do this in PHP?

  2. #2
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Well, you could go down the AJAX approach. If so, it's impeccable timing since I just posted on a thread about this: http://www.sitepoint.com/forums/showthread.php?t=571588
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  3. #3
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Execute another process in the background.

    See my answer for this thread
    http://www.sitepoint.com/forums/showthread.php?t=571451

  4. #4
    SitePoint Wizard
    Join Date
    Mar 2008
    Posts
    1,149
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Be aware that a user may run a script twice, so you don't want to have two processes enter any sort of race condition.

    In addition, depending on how you implement it, make sure that the script doesn't quit for whatever reason in the middle of processing.

  5. #5
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ArunB View Post
    I need to write a PHP script that takes a lot of time for execution. I need to give response to user by executing the script (first few lines) required for output and continue execution of the remaining script.

    Is there anyway I can do this in PHP?
    Yes, but more importantly: Why do you need this?

  6. #6
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Suppose a user is sending a request to a web page which takes one hour to complete. Response to send is just "OK" irrespective of the result. So, how can I sent that OK before starting the PHP script execution?

  7. #7
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ArunB View Post
    Suppose a user is sending a request to a web page which takes one hour to complete.
    Right. But how would you handle a failure then? Supposedly, during that hour, a lot of things could go wrong.

    If you actually have such long-running requests, you would be better off dropping it in a queue and have a cronjob churn through it.

  8. #8
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yep, I have plan for handling failure. Thanks for your suggestion.

    How to send response before continuing execution of script?

  9. #9
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do you also have a plan for handling lockup of server resources? PHP defaults to close any scripts that runs longer than 60 seconds. That's a security measure, that guards against scripts that get caught in infinite loops, as well as it gives some level of protection against malicious users making DoS type attacks.

    Anyway, the way to do it, is to first set execution time of your script to zero, with set_time_limit (~infinite), and then set ignore_user_abort. If you use sessions, make sure to end it with session_write_close, or you will prevent additional requests from the same user. Also make sure that you free any external resources that you don't need (Such as file handles or database connections), since they would otherwise block access.

  10. #10
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @kyberfabrikken

    Thank you very much. But, how can I send the response?

    And if there are any other precautionary measures, please tell me.

    Thank you.

  11. #11
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could calculate the Content-Length of the response and send it in the headers. The browser would disconnect after loading the specified number of bytes. Use set_time_limit(0) and ignore_user_abort(true) to make the script continue running after the disconnect, as kyberfabrikken suggested.

  12. #12
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by World Wide Weird View Post
    You could calculate the Content-Length of the response and send it in the headers.
    Is this is the correct technique?

  13. #13
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ArunB View Post
    Is this is the correct technique?
    It's one possible technique. There is always more than one way to do something. This seems the simplest way to me.

  14. #14
    SitePoint Wizard silver trophybronze trophy Stormrider's Avatar
    Join Date
    Sep 2006
    Location
    Nottingham, UK
    Posts
    3,133
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I can see many reasons for wanting to do this, I'd be interesting in finding out how as well.

    For example, a script that spiders lots of pages and outputs each page's status as it goes, something like that.

  15. #15
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ArunB View Post
    Thank you very much. But, how can I send the response?
    Try calling ob_end_flush to have the buffer sent right away.

  16. #16
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    Try calling ob_end_flush to have the buffer sent right away.
    If you want to get the content length, use ob_get_clean instead.

    PHP Code:
    <?php

    ob_start
    ();
    // generate response HTML here
    $response ob_get_clean();
    $contentLength strlen($response);
    header('Content-Length: ' $contentLength);
    echo 
    $response;

    ?>

  17. #17
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think, it is not working.
    After ob_end_flush(), I have kept an echo, and I got it in response!!!

  18. #18
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You may have to send a header("Connection: close") in addition to the Content-Length header. Also, you may have to call flush at the end.

    Eg.:
    PHP Code:
    <?php
    ob_start
    ();
    echo 
    "Should see this";
    $response ob_get_clean();
    $length strlen($response);
    header('Connection: close');
    header('Content-Length: ' $length);
    echo 
    $response;
    flush();

    echo 
    "Shouldn't see this";

  19. #19
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    As ob_start() is used, we have to use ob_flush() instead of flush().

    Is this statement is correct?

  20. #20
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @kyberfabrikken

    I have tried your example

    PHP Code:
    <?php
    ob_start
    ();
    echo 
    "Should see this";
    $response ob_get_clean();
    $length strlen($response);
    header('Connection: close');
    header('Content-Length: ' $length);
    echo 
    $response;
    flush();

    echo 
    "Shouldn't see this";
    And response is:

    Should see thisShouldn't see this
    The text "Shouldn't see this" is also sent to output.

    I have changed that flush() to ob_flush(). But no use.

  21. #21
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ArunB View Post
    As ob_start() is used, we have to use ob_flush() instead of flush().

    Is this statement is correct?
    No. ob_flush() flushes the output buffer (internal to PHP). flush() sends the contents from PHP to the web server.

    Whether or not this works, depends on the web server, so it may not be possible in your particular setup. Which web server are you using? Are you running PHP as CGI? The behaviour of output buffers also changed at some point; Which version of PHP are you using?

  22. #22
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What's the problem if I run PHP as CGI?

    I have installed ZendPlatform trial, which is causing PHP to run as CGI.

  23. #23
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, I don't know how ZendPlatform works, but most likely it's buffering the response or ignoring the Connection: close header. It works fine with mod_php + Apache.

  24. #24
    SitePoint Addict ArunB's Avatar
    Join Date
    Jun 2008
    Location
    Hyderabad
    Posts
    252
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What's the problem if PHP runs as CGI?

  25. #25
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ArunB View Post
    What's the problem if PHP runs as CGI?
    CGI doesn't have as much control over the web server, as mod_php has. Maybe ZendPlatform is buffering the response before sending it to the web server. Maybe it's ignoring the Connection: close header. I don't know specifically.


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •