Executing PHP code after a specific time - php

Let's say that there are two PHP functions.
function first()
{
$keyword = $this->input->post('keyword');
//search for the result and show it to users.
$this->search->search($keyword);
//send the keyword to save it into the db.
$this->second($keyword);
}
function second($keyword)
{
//saving a search keyword in the db
}
I would like to send the result as soon as possible and save the search word into DB.
However, I want to run the second script later after specific time.
because I want to deliver the search result as soon as possible to my customer.
Is there a way to run second PHP script after a user run the first PHP script?
* I don't want to use Cron Job
* I wanna run those two script separatly.
* don't want to use sleep because it will stop the first script for certain times.

You'll need to route it back round to your server, but this asynchronous php approach works quite nicely (I've been using it for about a year to do almost exactly what you seem to be doing).
See: How to run the PHP code asynchronous

Instead of making a web request from PHP, as suggested by Bob Davies, I would initiate a new HTTP request from the html page after the page has been shown.
For example:
Client makes an HTTP request (search)
Server gets the stuff and returns results to the end user
The result HTML contains a snippet, such as < img src="empty.gif?searchterm=mysearch"/> which initiates another request when browser renders the html
When that another request hits your server, you can save the search to DB
Similar methods are used to do for example client tracking, when you don't want the end user having to wait your metrics stuff. Some points:
It is quite simple to understand, implement and debug, which (to my opinion) doing HTTP requests on the server side aren't
It's more scalable
It doesn't require having javascript on, just a browser rendering the HTML
The target can be any server anywhere which doesn't have to be accessible from your web server, just to end user.

If you want to use PHP only then as far as I know, you can use sleep(), but it delays the execution of the code.
I think the easiest way to delay the job is with AJAX. Simply put the second function inside another PHP document and call XMLHTTPRequest() or $.ajax (if you want to use jQuery), and delay the code for some seconds. You can do that with setInterval(), or with delay() (jQuery).
Simply write
delay(2000).function(){
//saving a search keyword in the db
}
Remember that here you should use AJAX and not PHP code.

Related

Communication between web page and php script triggered from this web page

I have here an myAction function in some controller. And it has one class instance:
public function myAction() {
...
$myAnalyzer = new Analysis();
$myAnalyzer->analyze();
...
}
Let say this function analyze() takes 10 mins. That means it blocks my.phtml 10 mins, which is unacceptable. What I want is to render my.phtml first and then to show intermediate result from analyze() on my.phtml.
function analyze() {
...
foreach($items as $rv) {
...
...
// new result should be stored in db here
}
}
As far as I know, it's impossible, for there is just one thread in PHP. So I decided to ajax-call from my.phtml to run myAnalyzer instance.
First question: is that right? Can I do it in myAction() without blocking?
OK, now I run myAnalyzer using some script, say worker.php, from my.phtml with the help of javascript or JQuery.
Second question: how can I know when each foreach-loop ends? In other words, how can I let worker.php send some signal (or event) to my.phtml or zend framework. I do NOT want to update my.phtml on a time basis using javascript timer. That's all that I need to know, since intermediate data is supposed to be stored in DB.
Third question: the myAnalyzer muss stop, when user leaves pages. For that I have this code.
window.onbeforeunload = function(e) {
// killer.php kills myAnalyzer
};
But how can javascript communicate with myAnalyzer? Is there something like process-id? I mean, when worker.php runs myAnalyzer, it registers its process-id in zend framework. And when user leave page, killer.php stops myAnalyzer using this process-id.
I appreciate the help in advance.
First Q.: Yeah, I'm afraid that is correct.
Second Q.: I do not understand what do you mean here. See code example below
foreach($data => $item) {
...
}
//code here will be executed only after foreach loop is done.
Third Q.: Take a look at this page. You can set this to false (But I suppose it is already like that) and send something to client from time to time. Or you can set it to true and check if user is still connected with connection_aborted function. What I mean here is that you can run your worker.php with ajax and configure your request so browser will not disconnect it because of timeout (so connection will be kept while user stay on page). But it will be closed if user leave the page.
EDIT:
About second question. There are few options:
1) you may use some shared memory (like memcached, for instance). And call server with another ajax request from time to time. So after each loop is ended - you put some value into memcached and during request you can check that value and build response/update your page based on that value
2) There is such thing like partial response. It is possible to get some piece of response with XMLHTTPRequest, but as I remember - that is not really useful at this moment as it is not supported by many browsers. I do not have any details about this. Never tried to use it, but I know for sure that some browsers allow to process portions of response with XMLHTTPRequest.
3) You can use invisible iframe to call your worker.php instead of XMLHTTPRequest. In this case you can send some piece of where you can put a javascript which will call some function in parrent window and that function will update your page. That is one of Long-polling COMET implementations if you want to get some more information. There are some pitfalls (for instance, you may need to ensure that you are sending some specyfic amount of symbols in response in order to get it executed in some browser), but it is still possible to use (some web browser chats are based on this).
2) and 3) is also good because it will solve your third question problem automatically. At the same time 1) may be simpler, but it will not solve a problem in third question.
One more thing - as you will have long running script you must remember that session may block execution of any other requests (if default file based PHP session is used - this will happen for sure)

Write in MySQL database when something happens?

I'm building a game with javascript where you can walk and pick up things, right now it works fine but it doesn't save the things you have picked up on my database so when you quit the game you lose your progress.
I need to save to my database every time the user walks into something (when a div has a certain position). Right now there is a big javascript IF that basically deletes the item from the map.
Is it possible to make the javascript run the PHP code that writes in the database? How could I do it?
Since Javascript is client-side code, you can't simply call PHP (server-side code) with it. What you can do is post to a page that runs PHP code, using AJAX for instance.
The way you would do it is simple.
Every time the player does an action, have your script make an ajax call to the server to save the location (or what ever you are saving). You can just add a function to the part of your code, so when it is called, it sends the request in the background and saves the value to your databse. The only thing if that you would have to split the ajax requests up, so you only do one every 5-10 seconds. If you dont do this, then you would basically DDoSing you server.
you need ajax
http://code.google.com/edu/ajax/tutorials/ajax-tutorial.html

Is there a way to grab files from other servers and dump them into the DB asynchronous?

I need to create a php script that takes lots of URL's via POST and then loads the corresponding files and dumps them in the DB. The thing is that I would like to do it asynchronous, so that if I have 1000 files to get, the script won't hang till all the files are loaded. Also, every time a file it's done loading, I need to know so that I can insert it in the DB
Any ideas are appreciated.
Split the script in two parts - first to collect the URLs and the second is a shell script to be run from background to get the urls inserted in the database and fetch them.
So basically the process is as follows:
Script1:
Gets POST
Inserts into database
Call script 2 with
shell_exec to run in background
Script2:
Get all the urls from urls_to_download
Fetch the URLS (consequentially or parallel, depends on you)
Do stuff with them
Save them to database.
And you are done. The POST in script1 returns immediately and the script2 is then running. All left for you is to check status (poll from database through AJAX may be) for the URLS if you want to show some information about progress.
PHP is not multithreaded and perfectly synchronous. So you may not do this using PHP alone.
But you may use another language to do this task, for example JavaScript (which is asynchronous). Try node.js. It is lightning fast and has mysql bindings ;) Use http.Client to make the requests to the sites.

PHP display progress messages on the fly

I am working in a tool in PHP that processes a lot of data and takes a while to finish. I would like to keep the user updated with what is going on and the current task processed.
What is in your opinion the best way to do it? I've got some ideas but can't decide for the most effective one:
The old way: execute a small part of the script and display a page to the user with a Meta Redirect or a JavaScript timer to send a request to continue the script (like /script.php?step=2).
Sending AJAX requests constantly to read a server file that PHP keeps updating through fwrite().
Same as above but PHP updates a field in the database instead of saving a file.
Does any of those sound good? Any ideas?
Thanks!
Rather than writing to a static file you fetch with AJAX or to an extra database field, why not have another PHP script that simply returns a completion percentage for the specified task. Your page can then update the progress via a very lightweight AJAX request to said PHP script.
As for implementing this "progress" script, I could offer more advice if I had more insight as to what you mean by "processes a lot of data". If you are writing to a file, your "progress" script could simply check the file size and return the percentage complete. For more complex tasks, you might assign benchmarks to particular processes and return an estimated percentage complete based on which process has completed last or is currently running.
UPDATE
This is one suggested method to "check the progress" of an active script which is simply waiting for a response from a request. I have a data mining application that I use a similar method for.
In your script that makes the request you're waiting for (the script you want to check the progress of), you can store (either in a file or a database, I use a database as I have hundreds of processes running at any time which all need to track their progress, and I have another script that allows me to monitor progress of these processes) a progress variable for the process. When the process begins, set this to 1. You can easily select an arbitrary number of 'checkpoints' the script will pass and calculate the percentage given the current checkpoint. For a large request, however, you might be more interested in knowing the approximate percent the request has completed. One possible solution would be to know the size of the returned content and set your status variable according to the percentage received at any moment. I.e. if you receive the request data in a loop, each iteration you could update the status. Or if you are downloading to a flat file you could poll the size of the file. This could be done less accurately with time (rather than file size) if you know the approximate time the request should take to complete and simply compare against the script's current execution time. Obviously neither of these are perfect solutions, but I hope they'll give you some insight into your options.
I suggest using the AJAX method, but not using a file or a database. You could probably use session values or something like that, that way you don't have to create a connection or open a file to do anything.
In the past, I've just written messages out to the page and used flush() to flush the output buffer. Very simple, but it may not work correctly on every web server or with every web browser (as they may do their own internal buffering).
Personally, I like your second option the best. Should be reliable and fairly simple to implement.
I like option 2 - using AJAX to read a status file that PHP writes to periodically. This opens up a lot of different presentation options. If you write a JSON object to the file, you can easily parse it and display things like a progress bar, status messages, etc...
A 'dirty' but quick-and-easy approach is to just echo out the status as the script runs along. So long as you don't have output buffering on, the browser will render the HTML as it receives it from the server (I know WordPress uses this technique for it's auto-upgrade).
But yes, a 'better' approach would be AJAX, though I wouldn't say there's anything wrong with 'breaking it up' use redirects.
Why not incorporate 1 & 2, where AJAX sends a request to script.php?step=1, checks response, writes to the browser, then goes back for more at script.php?step=2 and so on?
if you can do away with IE then use server sent events. its the ideal solution.

On form submit background function php running

I am looking for a way to start a function on form submit that would not leave the browser window waiting for the result.
Example:
User fills in the form and press submit, the data from the form via javascript goes to the database and a function in php that will take several seconds will start but I dont want the user to be left waiting for the end of that function. I would like to be able to take him to another page and leave the function doing its thing server side.
Any thoughts?
Thanks
Thanks for all the replies...
I got the ajax part. But I cannot call ajax and have the browser move to another page.
This is what I wanted.
-User fills form and submits
-Result from the form passed to database
-long annoying process function starts
-user carries on visiting the rest of the site, independent of the status on the "long annoying process function"
By the way and before someone suggests it. No, it cannot be done by cron job
Use AJAX to call the php script, and at the top of the script turn on ignore_ user_ abort.
ignore_user_abort(true);
That way if they navigate away from the page the script will continue running in the backround. You can also use
set_time_limit(0);
to set a time limit, useful if you know your script will take a while to complete.
The most common method is:
exec("$COMMAND > /dev/null 2>&1 &");
Ah, ok, well you're essentially asking therefore, does PHP support threading, and the general answer is no... however...
there are some tricks you can perform to mimick this behaviour, one of which is highlighted above and involves forking out to a separate process on the server, this can be acheived in a number of ways, including the;
exec()
method. You also may want to look here;
PHP threading
I have also seen people try to force a flush of the output buffer halfway through the script, attempting to force the response back to the client, I dont know how successful this approach is, but maybe someone else will have some information on that one.
This is exactly what AJAX (shorthand for asynchronous JavaScript + XML) is for;
AJAX Information
It allows you to code using client side code, and send asynchronous requests to your server, such that the user's browser is not interuppted by an entire page request.
There is alot of information relating to AJAX out there on the web, so take a deep breath and get googling!
Sounds like you want to use some of the features AJAX (Asynchronous Javascript and XML - google) have to offer.
Basically, you would have a page with content. When a user clicks a button, javascript would be used to POST data to the server and begin processing. Simultaneously, that javascript might load a page from the server and then display it (eg, load data, and then replace the contents of a DIV with that new page.)
This kind of thing is the premise behind AJAX, which you see everywhere when you have a web page doing multiple things simultaneously.
Worth noting: This doesn't mean that the script is running "in the background on the server." Your web browser is still maintaining a connection with the web server - which means that the code is running in the "background" on the client's side. And by "background" we really mean "processing the HTTP request in parallel with other HTTP requests to give the feel of a 'background' running process"

Categories