Run background job and display results to the user - php

I have this php script that imports each row to my database. After it saves, in the same process it will do some more stuff, takes 1-2 sec for each row so my user prefers to send the CSV file to me, then I run in the terminal.
I want to build a page to him, so he can drop the CSV in a file input, until here ok, I saw how to make this run in background, but I really want to show in the page the results of importing, my scripts echoes the result for each row in the CSV in the terminal. How to do something similar in the HTML?
How to make the user drops the CSV in a file input and see the result for each row right bellow as like he had executed the script in a terminal on his screen?
EDIT (making things clear)
I want to display the script messages while it's running, I mean, for each row of the csv file, my script will output/echo the result of the import, I want to immediately display this row result to the user in the HTML page. Not after the script execution finishes. Something like a stream.

Sounds like you need to look at using jQuery and AJAX which will achieve what you're aiming for. This allows you to send data to a script, such as PHP, and the script processes in the background before sending the response.

Related

Display Live Progress and Any Errors During Long Script Execution in CodeIgniter

I'm working on an app that creates QR codes and renders them onto multiple graphics for a user.
The Problem:
I wrote a script to import users to create from a CSV. I'm needing to create over 100 users (each including the process above). Right now it takes roughly 1 minute to complete for each new user to complete the processing.. then spits out all my error/success messages at once.
My Question:
Rather than the browser slowly loading the result view (currently stays on a white page until complete) as my script is processing, is their a somewhat easy way to display the live progress and errors as they happen? Something like a progress bar updated as each user is created/fails. I'm guessing it will require AJAX?
When dealing with websites, remember the golden rule.
PHP MUST DIE.
Noobs assume this is people rubbishing PHP. It isn't. It's the HTTP request cycle.
Request In > PHP > Response Out > PHP process dies.
This is only the case when dealing with web servers and browsers, not CLI PHP. But the point is that you may end up getting Apache timeouts if your script takes as long as you say.
One solution could be to set up a cron that checks for a file and if it finds it, processes it, dumping a line number in a text file that your browser could check, which means you could fetch progress:
<?php
if (file_exists('/some/csv/to/process.csv')) {
// open file
// get row to work on
// process row
// update progress file with next line number
}
Meanwhile, you could set up a script that does this:
<?php
$progress = file_get_contents('/path/to/progress.txt');
header('Content-Type: application/json');
echo json_encode(['progress' => $progress]);
And then get the progress using AJAX inside a setInterval function:
$.get('/path/to/progress/json/page', function(data){
console.log(data);
});
Just an idea, may or may not suit you but give it a try!

Progress bar for an application

I have implemented a SAAS scenario with my Windows server: a user could upload a file in a website, then Fetch.exe is an application coded in C# hosted in the server, Fetch.exe takes the uploaded file as an input, executes and generates an output to download for the user.
So in my php, I use exec to wrap Fetch.exe:
exec("Fetch.exe " . $inputFile . " > " . $outputFile)
Uploading and executing (ie, Fetch.exe) may take more than several seconds, and I want to show the user that it is processing and everything is going fine.
I have found some threads that discuss how to show a progress bar for the uploading. Whereas, does anyone know what I could do to show the approximate progress of Fetch.exe? Do I have to split it into smaller applications and use several exec?
You could supply Fetch.exe with an randomly generated ID from php, for example from the uniqueid function. Fetch.exe will create a file called <uniqueid>.txt with a progress percentage. From the browser, you could call another script with that unique ID to get the contents of that .txt file. In order, it would be something like this:
User uploads the file to PHP
PHP:
handles the uploaded file
creates a uniqueID
starts Fetch.exe with the file and the uniqueID
returns a page with the uniqueID embedded
The following happens in parallel:
Fetch.exe creates a textfile called /progress/uniqueid.txt with the uniqueid as name. It logs the progress into it.
The browser does an AJAX call to http://example.com/progress/uniqueid.txt and shows the progress to the user
And finally, when the progress reaches 100% the browser downloads the file. The only thing you might want to add is the pruning of the progress files after a while. Say you delete all files older than 10 minutes every hour.
Your PHP program needs a way to know the state of the subprocess (the Fetch.exe application), so, Fetch.exe needs to send info about the processing state, the most natural way to do this is through the standard output (the standard output is the information that provides a program when you run it from cmd).
Knowing this, you can run and keep reading a subprocess output from php using popen().
And secod, you can use the PHP ob_flush() and flush() with the onmessage javascript event to establish the comunication from your client page with your running php script, here you can find a good tutorial on how do this.

Update Jquery progress bar, while reading txt file (from php)

I have a 100.000 rows txt file and I need to read it in order to insert most part of it into my DB.
I'd like to use this plugin, as I found it very easy to use:
http://www.bram.us/projects/js_bramus/jsprogressbarhandler/#download
My problem is: I read the txt file with PHP, but I don't understant how to update the progress bar!
I was thinking something like this
echo '$("#progressbar").progressbar({ value: '.($k++).' });';
where $k goes from 0 to 100, but, WHERE do I have to put it??
I've found this method:
http://spidgorny.blogspot.it/2012/02/progress-bar-for-lengthy-php-process.html
I think that this could help with some editing to the code.
You can't possibly mix the php and the javascript:
The PHP will run and generate an HTML/JS file
The HTML/JS file will be sent to the client
The client will run the JS: $("#progressbar").progressbar({ value: XX });
So k will be static.
--
If you really want to do something like that easily, you could use an intermediary DB table with three columns: txt_file, position, length
And often update this table while the PHP script is running over a txt file.
Client side, in Javascript, you can make an ajax request using jQuery for example every 5 or 10seconds, which is going to call an other PHP page, and this PHP page will only return the corresponding row from the intermediary table. Once you have the result you can update the progressbar.
--
It's the simplest solution to implement for you, but it's still really dirty, and the parsing of the txt file better have to be really long !
There is no direct method to achieve this thing. PHP script executes first and then the output is sent to the client viewing the web page that is why you cannot show live status of your PHP script's processing to the client.
You will have to use a combination of AJAX and Database :
Create a table to track the progress of the loading of the text file. Whenever a user (client) sends a request to the page, keep on updating the table with the progress. Use Session id as the index on the table so that it would be easy to track the progress per client. Now use AJAX requests to get the progress from the table and present it to the client with your progress bar.

PHP output messages while script in process

For example i'm looping through a big file, and after counter reaches 1000 parsed strings i need to echo message, that 1000 string have been parsed and calculate % of overall completed strings.
Is it possible to make something like that with output buffer?
Take a look at flush(). Whether or not your browser will render the incomplete page, or wait till it finishes loading is entirely implementation-dependent, though...
Make your script to write the progress data in a text file on the server. Now program your webpage with help of Ajax to send request to that file in particular intervals of time. Get the data and calculate the percentage and modify the HTML of your page.
One possiblity is to use another script to output the progress, and have the client poll it in set intervals for current progress, and only ask for the complete output after the whole process is complete.

PHP database simulation

I have a PHP script that works by calling items from a database based upon the time they were placed in there and it deletes them if they are older than 5 minutes. Basically, I want to now simulate what would happen if this database was being updated regularly.
So I was considering sticking in some code that loads an XML file then goes through and parses that into the database based upon the time data located within a node of the xml data... but the problem there is I want it to continually loop through an enter this data so it'll never actually run the other processes
So I was thinking of having another PHP script do that that could do this independantly of the php script that is going to display this data...
In theory:
I am looking to have a button that I can press and it will then run some php code to load up an XML file from a directory on my web server and then iterate though the data sending the data, to a database, based upon the time within a node in the PHP script and when the script was first called
So back to my page that displayed the data... if I continually hit refresh it will contain different results each time because data is being added by the other process and this php script removes the older data when it is refreshed
Any information on this?
Is there a way I can silently, and safely, run a php script without it being loaded into a browser... like a thread!?
Why not just run the PHP script that parses and inserts data into your DB from PHP's CLI?
http://www.php.net/manual/en/features.commandline.usage.php

Categories