Asked  7 Months ago    Answers:  5   Viewed   29 times

I'm attempting to do an AJAX call (via JQuery) that will initiate a fairly long process. I'd like the script to simply send a response indicating that the process has started, but JQuery won't return the response until the PHP script is done running.

I've tried this with a "close" header (below), and also with output buffering; neither seems to work. Any guesses? or is this something I need to do in JQuery?

<?php

echo( "We'll email you as soon as this is done." );

header( "Connection: Close" );

// do some stuff that will take a while

mail( 'dude@thatplace.com', "okay I'm done", 'Yup, all done.' );

?>

 Answers

85

The following PHP manual page (incl. user-notes) suggests multiple instructions on how to close the TCP connection to the browser without ending the PHP script:

  • Connection handling Docs

Supposedly it requires a bit more than sending a close header.


OP then confirms: yup, this did the trick: pointing to user-note #71172 (Nov 2006) copied here:

Closing the users browser connection whilst keeping your php script running has been an issue since [PHP] 4.1, when the behaviour of register_shutdown_function() was modified so that it would not automatically close the users connection.

sts at mail dot xubion dot hu Posted the original solution:

<?php
header("Connection: close");
ob_start();
phpinfo();
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();
flush();
sleep(13);
error_log("do something in the background");
?>

Which works fine until you substitute phpinfo() for echo('text I want user to see'); in which case the headers are never sent!

The solution is to explicitly turn off output buffering and clear the buffer prior to sending your header information. Example:

<?php
ob_end_clean();
header("Connection: close");
ignore_user_abort(true); // just to be safe
ob_start();
echo('Text the user will see');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush(); // Strange behaviour, will not work
flush(); // Unless both are called !
// Do processing here 
sleep(30);
echo('Text user will never see');
?>

Just spent 3 hours trying to figure this one out, hope it helps someone :)

Tested in:

  • IE 7.5730.11
  • Mozilla Firefox 1.81

Later on in July 2010 in a related answer Arctic Fire then linked two further user-notes that were-follow-ups to the one above:

  • Connection Handling user-note #89177 (Feb 2009)
  • Connection Handling user-note #93441 (Sep 2009)
Tuesday, June 1, 2021
 
Jauco
answered 7 Months ago
80

dataType - delete this one.

Add console.log and open console in Your browser

success: function (data) {
   console.log( data );

show Your console, and then You will see why. Maybe an unwanted char or php error

Second thing - there should be if stament like this (I supposed)

if (data == "1") // it is returning string, not integer.

You can also try to use switch case in success.

Wednesday, March 31, 2021
 
CodeCaster
answered 9 Months ago
86

I've written about this in a post on my blog. The trick is to use reflection to poke values in as a way to get access to the non-public fields (and methods).

eg.

var settings = ConfigurationManager.ConnectionStrings[ 0 ];

var fi = typeof( ConfigurationElement ).GetField( "_bReadOnly", BindingFlags.Instance | BindingFlags.NonPublic );

fi.SetValue(settings, false);

settings.ConnectionString = "Data Source=Something";
Wednesday, June 2, 2021
 
seaders
answered 7 Months ago
37

add target=_blank in your ajax success function like below

success: function(){
  window.open('http://YOUR_URL','_blank' );
},

otherwise you can handle smartly to open your Excel download link in new tab with jQuery trigger function or etc.

Monday, July 19, 2021
 
Jubair
answered 5 Months ago
81

Your connection info would go in the MySQLDB class, so you could have something like this:

class MySQLDB implements IDatabase
{
    private $pdo; // Holds the PDO object for our connection

    // Or you can remove the parameters and hard code them if you want
    public function __construct( $username, $password, $database) {
        $this->pdo = new PDO( '...'); // Here is where you connect to the DB
    }

    public function query( $sql) {
        return $this->pdo->query( $sql); // Or use prepared statments
    }
}

Then you instantiate it outside of the class:

$db = new MySQLDB( 'user', 'pass', 'db');

And pass that $db object to one of your classes expecting an IDatabase:

$obj = new Test( $db); // Dependency Injection, woo hoo!

You can also look into having the MySQLDB class extending the PDO class, but that is your design choice.

Finally, you might be better off just sticking with PDO and getting rid of all this, as it is a great abstraction layer that works with many different databases.

Thursday, August 19, 2021
 
Jeff Mercado
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share