Thread: Cancel a query when user leaves a web page

Cancel a query when user leaves a web page

From
Noel
Date:
Hi all,

I have a small problem. Is it possible to cancel a running query when a person leave or pressed the stop button in my web page.

I've been thinking about mixing php and javascript. Is this the best way to go about it?

basic out line of my code:
<html><head>....stuff....</head>
<body>...stuff
<?php
    $connection = pg_connect(host, dbname, user);

    pg_send_query($connection, "SELECT * FROM blah");

    // collect the results and display etc..
?>
</body></html>
The query can take some time.
And when the page is left the query is still running on postmaster.

Have tried
<?php
    include "functions.php";
    $connection = pg_connect(host, dbname, user);
?>
<html><body onunload(<?close_connection($connection)?>)>
<?php
    echo $connection;
    pg_send_query($connection, "SELECT * FROM blah");

    // collect the results and display etc..
?>
</body></html>

The function, close_connection($connection), is defined in the include file, which is the connection is busy, cancels the query and closes the connection.

This gives the following error:

Resource id #1
Warning: pg_send_query(): 1 is not a valid PostgreSQL link resource in /home/fauxn/public_html/singleAArepeats/test.php on line 11

Any suggestions welcome.

Many thanks
-- 
Noel Faux
Department of Biochemistry and Molecular Biology
Monash University
Clayton 3168
Victoria
Australia

Re: Cancel a query when user leaves a web page

From
ljb
Date:
noel.faux@med.monash.edu.au wrote:
> I have a small problem. Is it possible to cancel a running query when a
> person leave or pressed the stop button in my web page.
> ...
> Have tried
> <?php
>     include "functions.php";
>     $connection = pg_connect(host, dbname, user);
> ?>
> <html><body onunload(<?close_connection($connection)?>)>
...

This will never work, as you found. The Javascript action is client-side
and PHP is server-side.

Try using register_shutdown_function() to register a function which will
call pg_cancel_query(). As long as PHP isn't ignoring user aborts (see
ignore_user_abort()), your query will be cancelled when the user hits STOP.
Another way is to ignore user aborts, and while waiting for the
asynchronous query to finish, keep calling connection_aborted() to see if
you are still connected to the user; if not you cancel the query and exit.

Re: Cancel a query when user leaves a web page

From
"Muhyiddin A.M Hayat"
Date:

<body onunload(<?close_connection($connection)?>)>

onunload above can't call function from PHP, but it called from javascript, you can create javascript function to call PHP function/file that you wanna PHP do 

<?php
// close_connection.php

include(
'connection.php');
global
$connection;

function close_connection(
$connection){
// close_connection here
// .....
// .....
// .....

}

close_connection(
$connection);
echo
"<SCRIPT>window.close();</SCRIPT>";
?>

---------

<html>

<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
function leave() {
window.open('close_connection.php','','toolbar=no,menubar=no,location=no,height=10,width=10');
}
// End -->
</SCRIPT>

<body onunload = "leave()">

</body>
</html>

----- Original Message -----
From: Noel
Sent: Tuesday, November 18, 2003 10:33 AM
Subject: [PHP] Cancel a query when user leaves a web page

Hi all,

I have a small problem. Is it possible to cancel a running query when a person leave or pressed the stop button in my web page.

I've been thinking about mixing php and javascript. Is this the best way to go about it?

basic out line of my code:
<html><head>....stuff....</head>
<body>...stuff
<?php
    $connection = pg_connect(host, dbname, user);

    pg_send_query($connection, "SELECT * FROM blah");

    // collect the results and display etc..
?>
</body></html>
The query can take some time.
And when the page is left the query is still running on postmaster.

Have tried
<?php
    include "functions.php";
    $connection = pg_connect(host, dbname, user);
?>
<html><body onunload(<?close_connection($connection)?>)>
<?php
    echo $connection;
    pg_send_query($connection, "SELECT * FROM blah");

    // collect the results and display etc..
?>
</body></html>

The function, close_connection($connection), is defined in the include file, which is the connection is busy, cancels the query and closes the connection.

This gives the following error:

Resource id #1
Warning: pg_send_query(): 1 is not a valid PostgreSQL link resource in /home/fauxn/public_html/singleAArepeats/test.php on line 11

Any suggestions welcome.

Many thanks
-- 
Noel Faux
Department of Biochemistry and Molecular Biology
Monash University
Clayton 3168
Victoria
Australia

Re: Cancel a query when user leaves a web page

From
Noel
Date:
Hi all,
Sorry for the delayed response, I've added both Hayat's and ljb220's suggestions.

I've tried both, but still having problems.
Code:
//----------------------
test.php
<html>
<script language="JavaScript">
<!-- Begin
function leave() {
    window.open('close.php','','toolbar=no,menubar=no,location=no,height=10,width=10','');
}
// end -->
</script>
<body onunload = 'leave()'>
<?php include "functions.php";
    global $connection;
    $connection = pg_connect("host=localhost dbname=test user=test");
    echo $connection." connection <br>";
    echo pg_connection_status($connection)." status<br>";
    pg_send_query($connection, "SELECT COUNT(id) FROM test"); // expected to take ~2min enough time to press stop
    echo pg_connection_busy($connection)." busy<br>";
    $res = pg_get_result($connection);
    echo pg_num_rows($res)." # rows<br>";
    echo $GLOBALS["connection"]." GLOBALS<br>";
?>
</body></html>

//--------------------------------------
close.php
<?php include "functions.php";
    echo "closing connection<br>";
    $f = fopen("/home/xxx/log","w"); // log file to trace the code etc...
    fwrite($f,"new page\n");
    fclose($f);
    close_con();
    echo "closed";
    echo "<script>window.close();</script>";
?>

//--------------------------------
functions.php
<?php
/* when the page is exited, if the connection is not null, cancel and sql statements and
      close the database connection */
    function close_con() {
        $f = fopen("/home/xxx/log","w"); // log file to trace the code etc...
        $connection = $GLOBALS["connection"];
        fwrite($f,"Closing connection\n");
        $status = pg_connection_status($connection);
        fwrite($f, $status." status\n");
        if($status == 0){// connected
            fwrite($f, "connected\n");
            if(pg_connection_busy($connection)) {// busy so cancel last query
                fwrite($f, "connection busy\n");
                pg_cancel_query($connection);
                fwrite($f, "query killed\n");
            }
            // close connection
            pg_close($connection);
            fwrite($f, "connection closed");
        }
        else {
            fwrite($f, "not connected\n");
        }
        fclose($f);
    }
?>

With this set up, the user enters test.php. Stops before the query finishes. It should call leave(). However, this dose not happen. I believe it is because the script has not finished and passed the page text to the browser (pls correct me if I'm wrong), until php has finished processing it.

I've tried using register_shutdown_function() as:
test.php
<html>
<body>
<?php include "functions.php";
    global $connection;
    $connection = pg_connect("host=localhost dbname=test user=test");
    register_shutdown_function("close_con");
    echo $connection." connection <br>";
    echo pg_connection_status($connection)." status<br>";
    pg_send_query($connection, "SELECT COUNT(id) FROM test");
    echo pg_connection_busy($connection)." busy<br>";
    $res = pg_get_result($connection);
    echo pg_num_rows($res)." # rows<br>";
    echo $GLOBALS["connection"]." GLOBALS<br>";
?>
</body></html>

The functions.php as above.

This also dose not work as, " The registered shutdown functions are called after the request has been completed" (from http://au2.php.net/manual/en/function.register-shutdown-function.php ). I'm interpreting that as, any functions in the list will not be
called until the pg_send_query() or the pg_get_result(), not sure which, returns. Then close_con() from functions.php is called via register_shutdown_function(). Thus I'm unable to cancel the query :(

Any comments, suggestions or work arounds would be greatly appreciated.

I'm using PHP 4.2.3

Cheers
Noel

//-----------------------------------------------------------------------------
Muhyiddin A.M Hayat wrote:

<body onunload(<?close_connection($connection)?>)>

onunload above can't call function from PHP, but it called from javascript, you can create javascript function to call PHP function/file that you wanna PHP do 

<?php
// close_connection.php
include(
'connection.php');
global
$connection;

function close_connection(
$connection){
// close_connection here
// .....
// .....
// .....

}

close_connection(
$connection);
echo
"<SCRIPT>window.close();</SCRIPT>";
?>

---------

<html>

<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
function leave() {
window.open('close_connection.php','','toolbar=no,menubar=no,location=no,height=10,width=10');
}
// End -->
</SCRIPT>

<body onunload = "leave()">

</body>
</html>

//----------------------------------------
ljb wrote:
noel.faux@med.monash.edu.au wrote:
I have a small problem. Is it possible to cancel a running query when a 
person leave or pressed the stop button in my web page.
...
Have tried
<?php   include "functions.php";   $connection = pg_connect(host, dbname, user);
?>
<html><body onunload(<?close_connection($connection)?>)> 
> ...
>
> This will never work, as you found. The Javascript action is client-side
> and PHP is server-side.
>
> Try using register_shutdown_function() to register a function which will
> call pg_cancel_query(). As long as PHP isn't ignoring user aborts (see
> ignore_user_abort()), your query will be cancelled when the user hits STOP.
> Another way is to ignore user aborts, and while waiting for the
> asynchronous query to finish, keep calling connection_aborted() to see if
> you are still connected to the user; if not you cancel the query and exit.


-- 
Noel Faux
Department of Biochemistry and Molecular Biology
Monash University
Clayton 3168
Victoria
Australia