I would like to refresh a page as soon as a processs on the server is completed. I wouldn't know where to begin or where to start my search.
I have to following scheme, which works perfectly:
A user uploads a file to the server via a website
The server checks whether the file is valid and copies the file to another folder.
In the other folder the file has to wait to be processed by a program (Filemaker Server) that is scheduled to run every 1 minute (or whatever interval).
After the program has finished processing the file it marks a MySQL database entry with "0 no error" or whatever was returned by the process.
So far so good. I would like the user of the website to know when the process is ended. I already have a timer that counts down to 0, which is the amount of seconds until the processing starts. The user is then presented with the text "processing started".
Now, I would like to send a refresh request to the client browser at the moment the processing ends. This should be either some batch file command or a mysql function; I really don't have a clue. I did try <META HTTP-EQUIV="REFRESH" CONTENT="1";URL=home.php">, but the refreshes (every 1 second or any other interval) are not acceptable, because the user has to upload a file through a form which is unfortunately cleared whenever a refresh takes place. (This is not a problem when a server request would refresh the page, because only one upload process can take place at a time.)
Thanks in advance for any suggestions on this matter!
Have you ever read on AJAX?
I think a jQuery Ajax Upload is everything you need of. In the server-side you get the script, treat it, upload it, insert into the database some information regarding it, and then you inform the client-side the upload is over and the insertion has been successfully.
use javascript:
<script rel=JavaScript>window.location="home.php";</script>
I finally settled for using AJAX as per Ivo's suggestion. It is fairly easy to use! Thanks!
Related
I have a webform that sends data to PHP script.
PHP script may take a while to process the data. What I want to do is to send raw data to database, then redirect the visitor to "thank you" page and then continue processing the data in background. Important thing is that the script must continue working even if the visitor closes "thank you" page.
Can you advise which solution should I look into?
P.S. I use nginx + php-fpm if that matters.
UPDATE. I've found info about using ignore_user_abort(true). Could this be the way to go?
What I want to do is to send raw data to database, then redirect the visitor to "thank you" page and then continue processing the data in background.
That basically describes how I'd do it right there, actually.
Consider two separate applications. One is the web application, which saves the user input to the database and then continues to interact with the user. The other is a scheduled console application (a standalone script invoked by cron most likely) which looks for data in the database to be processed and processes it.
The user uploads the data, receives a "thank you" message, and his/her interaction is complete. The next time the scheduled task runs (every couple minutes, maybe?) it sees the pending data in the database, flags it as being processed (so if another instance of the script runs it doesn't also try to process the same data), processes it, flags it as being done (so it doesn't pick it up again next time), and completes.
You can notify the user of the completed process a couple of different ways. The back-end script can send the user an email (active notification), or perhaps the web application can examine the table for the flagged completed records the next time the user visits the page (passive notification).
Something like this should work :
pclose(popen('php script.php &', 'r'));
http://fr2.php.net/manual/fr/function.popen.php
You can also use more options or others functions to get more control over the execution :
http://fr2.php.net/manual/fr/function.proc-open.php
But use this carefully and be sure you need this way to resolve your problem.
Ajax would be nice.
You need to do the thing asynchronously. Use AJAX to achieve this
I would like to find a way to have my user not having to wait for the output of a php script and being redirected to a page while the script is running on the server.
Basically the user submits a form which takes quite long to process and I would like to redirect the user to a page notifying him that the form is being processed and that its output will be later available (I thought about opening a tab when the output is ready).
Basically I would like something like this, which I tried without success, the
if ($form_valid) {
process_form(); // this would need not to be running on the current page so that the user don't have to wait for it to be ready (timeout problems)
header('Location: http://example.com/form_submitted_output_coming_soon.html');
}
I hope that it is not too vague.
Thank you in advance for any help / advice on how I could do that.
It really depends on the time the script takes to execute if it's seconds, under 10 I would do an ajax request and have a modal progress message
If they take extended amounts of time my approach would be to create or use an existing task scheduler/ report generator
a single system scheduled task entry calling a central management script ( probably not optimal )
You mark a task/report for execution
Concurrency. Count, limit the number currently executing ( so you don't over load the server)
users pool via ajax for their tasks / reports or push to the clients with web sockets
Example on how to fork php to background
Update
I think you would get better performance out of a bot continuously check a database or file for work to do and submitting results back to the database. Alerting users via ajax, web sockets and or email when the work that they need is done / updated.
Here is a good introduction on how to build a web crawler in php
The best approach for solving this kind of problem is to use AJAX to make the request to the server in the background and then update the user once it has finished processing.
You may submit the form with an asynchronous request (ajax) and handle the page forward also with javascript. This way your form is handled asynchronously - you may even wait for the response to tell the user once you have an answer. This asynchronous request will not block the UI.
Just for completeness if you really really want to use php only for this:
Run PHP Task Asynchronously
I have a php script that gets user input (some text and a link), puts it in the database and then using the link the user provided, it searches for an image.
The problem is, sometimes it takes a while to search for the image, and this makes the website 'stuck', so the view that says 'Your post has been submitted!' sometimes takes between 4 to 6 seconds to finally load.
Is there a way to make PHP search for the image asynchronously?
You may be wondering why don't I just load the view and then do the image search, or just use AJAX. Well, I need the 'last insert ID' from the database to rename the image according to the item ID, and this can only be done once the post has been inserted in the database.
EDIT 1: I have already read this Asynchronous PHP calls? but I am not sure I understand.
EDIT 2: Here is an overview of the process as requested:
Step 1: User opens form and fills 2 fields (some text and a link)
Step 2: User submits form
Step 3: PHP inserts post in MySQL database
Step 4: PHP searchs for an image of that link (crawls the web, takes a few seconds) and saves the image with the name of the last ID from database insert. If last ID was 75 image will be saved as 'img_75'.
Step 5: PHP loads 'You have succesfully posted a link'
What I want is step 5 to happen just after step 3, while step 4 is running. I don't actually need the response from step 4. As long as it runs on the background I am happy :)
SOLUTION: I have done what #shadyyx suggests. A simple AJAX call. I really hoped for an alternative but apparently not php nor any other server side language can handle asynchronous calls.
I would do this in a two step AJAX call.
Here is what should it look like:
User opens a form and fills in the data
User clicks on submit button - an AJAX call is sent to the server
A new entry is written into the database and last ID is returned as response back to JS
You show user the message that the form was submitted
and call new AJAX request that will crawl the desired URL, download and save the image with the ID You got from the first AJAX response...
Clear? Easy? I guess it is...
I used processes for this.
the client requests
the server answers and gives the client an answer ID
the server starts a php process which does long running stuff in background and saves the result to a file
the client requests the answer with the ID every few seconds
when everything is in the file the server loads it and sends the result on an answer-request of the server.
used popen() for this...
also the server could tell the client a time-span which the client should wait till requesting the answer.
Why not creating a new record, returning last id immediately, and running the new query for updating the record with information?
Here is what I suggest for your case:
Send out a cookie to the browser when you have the form page being loaded.
The requests for the image should not (and must not) depend on the record that 'would be' inserted.
The image you are searching for is to be saved in some temporary path. Associate that path to the cookie. In PHP, you could use $_SESSION[...]. This would be an AJAX request as soon as the user fills out the required fields.
When form is submitted to the server:
Server gets the image from the $_SESSION variable.
PHP moves the file from the temporary location to the actual location.
Updates the DB.
Why you should not create a record prematurely
What would happen when AJAX request has struck the server(and the record is created) and then the user navigates away? In such cases you need to have additional constructs to remove that record, which is some sort of extra stuff you wouldn't want to get into.
I have already read this Asynchronous PHP calls?
The quality of the answers there could be better.
but I am not sure I understand
err, then maybe you might not understand the answers here.
The short answer is that you can't write asynchronous PHP code.
A longer answer is that you can make parallel HTTP requests from PHP (but still blocking) using the curl_multi_ functions, however if you want to generate a page from PHP without blocking then you'll have to generate HTML containing AJAX calls and let the browser handle the concurrent requests and populate them into the page when completed. Using this approach you have the option of invoking mulitple search threads on your DBMS which (if done right) should run faster than a single request.
I've recently finished my application and I've got a huge problem. I need to allow only 1 user to access it at a time. There is an index page accessible for every user everytime and "start" button. When user clicks start, the application locks and other ppl need to wait until the user finishes. When the user closes tab/browser, the application has to unlock automatically. Each user has 5 minutes to use my app.
I partially solved my problem, but it still doesn't work properly - on every site I set the jquery script that every 5 seconds triggers "extend.php" file on the server ($.get() function). The php file modifies time.txt file (it changs it to time()+5) and the script on the intex site checks whether (time()>time.txt content). So that when the uses closes tab/browser, the app is accessible. Obviously my app is also based on sessions (when the user closes browser, he loses access).
On some computers it simply doesn't work (it seems jquery doesnt trigger extend.php file and it makes my app accessible all the time).
So my question is: do you see any other ways to solve my problem?
The descr might be messy but I wanted to describe everything strightforward ;)
Regards.
Try using an a jQuery unload function so that when they click the close button your web browser executes one last line of script before the user exits. Example:
$(window).unload(function(){
"your php function to unlock the app here"
});
Hope this helps.
Your method is OK, it should work. Yes, node.js, or any other server side javascript can be used to do the same, but having a script triggered is by far the easiest solution. You really should focus your time to investigate further on what machines it is not working.
If it is restrained to 5 minutes, then set it to expire in 5 minutes. You can use a counter in jquery to show how much time is available. When it hits the expiration then notify the user time is up. Once time has expired or the user is finished with the app update the time.txt to time() or however you normally handle it when the app is accessible. No polling and 1 update.
You can put a LOCK on a mysql table when a user is online and unlock it when they are offline.
The only issue is if your code forgets to unlock.
If a user clicks a button that will make an ajax post call to a php file, then navigates away from the website or closes the window, will the php file run completely until it finishes?
i want the file to download stuff to my server and post a bunch of information into a mysql database. This could take a minute or two. But i want the task to finish completely no matter what the user does.
if the ajax post/request gets sent, will the file run through completely?
thanks for any info.
This should help:
ignore_user_abort(true);
set_time_limit(0); // number of seconds (0 infinity)
Check out the documentation for those two functions for more insight. In general, you shouldn't have a problem, as long as you don't run up against the time limit. This should have all the info you need:
http://us3.php.net/manual/en/features.connection-handling.php
this helped me understand:
http://www.php.net/manual/en/features.connection-handling.php