0

I have a php script with javascript code on it and I am sending an AJAX get() request to a second php script. The second script starts running. How to terminate the second script from the first?

  • 1
    It starts running. What do you mean with that? And what does the code look like? – putvande Nov 08 '13 at 14:44
  • 1
    Why do you need to "terminate" it? Is it running in a loop that doesn't have a natural exit condition, so that you need to *tell* it it's time to ext? Or is it just slow and you want to actually *kill* it? In the latter case (forcibly killing the process) details about your web server set up (Apache mod_php? fastcgi? Nginx? etc) will make a difference to the answer. – IMSoP Nov 08 '13 at 14:44
  • possible duplicate of [Abort Ajax requests using jQuery](http://stackoverflow.com/questions/446594/abort-ajax-requests-using-jquery) – Vlad Preda Nov 08 '13 at 14:46
  • 1
    I have a page with a custom on the fly generated image. I want, if the user decides to request a new image, free the server from working on the first one. –  ShadowHero Nov 08 '13 at 14:47
  • 1
    @Adam: I tried abort but abort doesn't kill the process. It just stop listening ti the server's response. –  ShadowHero Nov 08 '13 at 14:47
  • Does the image generation have multiple steps? Basically what I'm trying to get at is, are there places where the long-running PHP script can "listen" for a command that says "actually, stop what you're doing"? – IMSoP Nov 08 '13 at 14:50
  • Also, when you say "I have a PHP script with javascript code on it" - forget that that's a PHP script. As far as this problem is concerned, you have a page with JS running on it, and a PHP script which generates an image. The PHP script which generated the JS page has long since finished executing. – IMSoP Nov 08 '13 at 14:51
  • Yes, it has finished executing, but if the user presses a button, the script will start again. –  ShadowHero Nov 08 '13 at 14:52
  • Cant help you until you POST YOUR CODE – Dave Nov 08 '13 at 14:54
  • That's not what I meant. There is no "a php script with javascript code on it", only "a PHP script which generates an HTML page", and "an HTML page which has javascript code on it"; the two are not really the same. – IMSoP Nov 08 '13 at 14:54
  • @Dave: my code is: $.get('action.php', function(data) {alert("ok");}); –  ShadowHero Nov 08 '13 at 14:58
  • and the contents of your action.php are? and the creation of your data is? and the ajax requests are? have you got listeners and long wait sockets in use or just standard http requests? etc etc etc – Dave Nov 08 '13 at 14:59
  • and the contents of your action.php are -> nothing special. A long multi-step page witch returns an image with 'echo' in the end. Nothing more. No sockets or special code. The AJAX request is performed when a user clicks a button. If the user clicks again the same button, I want to end the script witch started on the first click. –  ShadowHero Nov 08 '13 at 15:03

2 Answers2

4

Based on clarifications in the question comments, it seems that what you have is this:

  1. an HTML page which the user interacts with using JS (this page was probably generated with PHP, but that's irrelevant to this scenario).
  2. an AJAX call from the page (1) calls a PHP script which generates an image, which is a slow and expensive process
  3. you want an extra AJAX trigger which will abort the currently running script (2)

The basic approach I would take would be to have some kind of "lock" or "trigger" which script (2) creates when it starts, and periodically checks between steps. The trigger could be a file, or a row in a database, etc - the key is that it needs to be somewhere that more than one PHP script can access simultaneously.

The script at (3) can then be a very small PHP script which deletes the particular file/database row/etc which you want to abort. When the script at (2) next checks, it will find that its lock/trigger no longer exists, and can then tidy up any working data its created and exit.

Make sure in doing this that you think about security: the name of the trigger will have to be known to the JS, and therefore can be manipulated by the user. It should be sufficiently random that someone can't maliciously abort all processes, and sufficiently restricted in its format that the abort script can't be tricked into deleting a file which has nothing to do with it. This isn't actually that hard - just a random string of numbers and letters will do - but the delete script needs to make sure that is actually the format it receives, as it cannot trust the JS to do so.

A variation on this is to have a "heartbeat" system, where a JS timer periodically updates the lock/trigger with a timestamp to say "yes, please keep processing this"; if the script at (2) spots that the timestamp is too old, it aborts. This approach is advantageous if you want to abort execution if the user gets bored and leaves the page, since you can't reliably capture that as an event and send a specific "abort" request (consider, for example, the user simply unplugging their laptop from the internet).

Beyond "stop!" and "keep going!", you can actually use this approach to communicate anything to the running PHP process, just by writing it to the file or database. Since there's no "event" model in PHP, or any kind of threading (without getting into quite complex 3rd party extensions), the only way for a PHP script to discover things have changed after it has started running is to actively query them, so long-running scripts should be structured where possible so that they can periodically "check their mail", so to speak.

IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • Thanks a lot. this is a great idea. I will do it with a file/database, if it's my last option. Isn't there any other way to archive the same thing, like get process id and kill it using that id? Or, have the ajax send data to the php file, somehow? –  ShadowHero Nov 08 '13 at 15:08
  • I was in the middle of writing essentially the same! +1 from me :) – Jaroslav Nov 08 '13 at 15:10
  • This is a *much* cleaner approach than trying to kill the process. Firstly, this affords the script a chance to clean up after itself in a controlled way (e.g. deleting temp files). Secondly, in some web server configurations, killing off PHP processes manually could cause unwanted instabilities. Finally, you would need some way of tracking which process ID to kill, verifying it, etc, which would actually end up more complex than just giving the process your own identifier (the lock/trigger) and using that to "communicate" with it. – IMSoP Nov 08 '13 at 15:11
  • Oh, and if you want to send more complex data than "stop!" or "keep going" to the PHP script, just write other data to the file/database row - the PHP script will still need to stop and read it periodically, because there is no "event" model (or even threads) in a PHP script. – IMSoP Nov 08 '13 at 15:13
  • OK, great, 5 stars! :D –  ShadowHero Nov 08 '13 at 15:25
0

You can interrupt the ajax query.

If you use jQuery, for example, in your file1.php, you request the file2.php via ajax call:

<script>
var jqxhr = $.get( "file2.php", function( data ) {
  // do some thing.
  alert( "Get was performed." );
});
</script>

And later in the same file1.php, later by clicking on a button or other user action/event handler,

<script>
//kill the request

jqxhr.abort();
</script>

This is just a possibility.

jacouh
  • 8,473
  • 5
  • 32
  • 43
  • 1
    I tried this. I tried abort but abort doesn't kill the process. It just stop listening ti the server's response. –  ShadowHero Nov 08 '13 at 14:56
  • We cannot get the process ID (Linux PID) of the new php executing process (file2.php), we may have no control over it ? – jacouh Nov 08 '13 at 14:58