I'm have a long-running perl script that outputs the percentage complete. How do I show the completion status real-time on a php page?
Example:
perl:
my $i = 0;
for $i (1 .. 6) {
print "$i\n";
sleep 1;
}
print "script end\n";
exit;
php:
echo passthru('perl testprint.pl');
This works to display the output, but not real-time.
Modify your perl script to pipe the output to a flat file. Use a php script to parse this file and output in whatever format you want.
You could call the php script from your html page using ajax, or if you save the perl script in the server's CGI directory you can call it directly without the need for the extra php file.
Lastly, create a nifty progress bar and profit.
For that you need to utilize AJAX.
I would have a PHP script that looks at the status, and then have AJAX update the status for the user to see.
Related
I have a php script which is something like below.
script.php
<?php
foreach($available as $loop)
{
echo file_get_contents($loop);
}
?>
basically loop runs like 100 to 200.When I run domain.com/script.php on browser..output is displayed only after all the loop is completed.But I want the page to update the output in realtime.
Is it posible by setting some kinda of header in php script or via htacces ?
You can do this with some servers using the flush() function.
You may be better off using JavaScript and AJAX to fetch and display progress of your long-running task, though.
I'm looking to run a program, and for every output line it generates, execute a PHP script and pass the line content to it.
I know, pretty hard to understand. Here's an example:
Execute script -> script outputs 'Initializing script on 127.0.0.1'. Now it needs to execute a command like php5 input.php 'Initializing script on 127.0.0.1'.
Is this doable? If so, how would I go about doing this?
Edit: to clarify; I basically want command > log.txt but in stead of writing the output to that file, writing it to a PHP script as an argument
PHP is an interpreter much like Bash, Python, etc, so you can do "normal" scripting with it. For example:
#!/usr/bin/php5
<?php
echo "Hello, world!\n";
while($line = fgets(STDIN)) {
echo "> " . $line;
}
?>
Mark the file as executable, then run:
$ /program/that/generates/lines | /path/to/your/php/script
However, contrary to your original question, it sounds to me like you actually want to use JavaScript and possibly AJAX for web purposes. Sane web applications will have the said script run in the background and safely write the results to a file or stream, using AJAX to read it and update the information on the current page.
I'm trying to find a way in which I can echo out the output of an exec call, and then flush that to the screen while the process is running. I have written a simple PHP script which accepts a file upload and then converts the file if it is not the appropriate file type using FFMPEG. I am doing this on a windows machine. Currently my command looks like so:
$cmd = "ffmpeg.exe -i ..\..\uploads\\".$filename." ..\..\uploads\\".$filename.".m4v 2>&1";
exec( $cmd, $output);
I need something like this:
while( $output ) {
print_r( $output);
ob_flush(); flush();
}
I've read about using ob_flush() and flush() to clear the output buffer, but I only get output once the process has completed. The command works perfectly, It just doesn't update the Page while converting. I'd like to have some output so the person knows what's going on.
I've set the time out
set_time_limit( 10 * 60 ); //5 minute time out
and would be very greatful if someone could put me in the right direction. I've looked at a number of solutions which come close one Stackoverflow, but none seem to have worked.
Since the exec call is a blocking call you have no way of using buffers to get status.
Instead you could redirect the output in the system call to a log file. Let the client query the server for progress update in which case the server could parse the last lines of the log file to get information about current progress and send it back to the client.
exec() is blocking call, and will NOT return control to PHP until the external program has terminated. That means you cannot do anything to dump the output on a line-by-line basis because PHP is suspended while the external app is running.
For what you want, you need to use proc_open, which returns a filehandle you can read from in a loop. e.g.
$fh = proc_open('.....');
while($line = fgets($fh)) {
print($line);
flush();
}
There are two problems with this approach:
The first is that, as #Marc B notes, the fact that exec will block until it's finished. You'll have to devise some way of measuring progress.
The second is that using ob_flush() in this way amounts to holding the connection between server & client open and dribbling the data out a little at a time. This is not something that the HTTP protocol was designed for and while it might work sometimes, it's not going to work consistently - different browsers and different servers will time out differently. The better way to do it is via AJAX calls: using Javascript's setTimeout() function (or setInterval()), make a call to the server periodically and have the server send back a progress report.
So I am trying to execute some script from my php code. That lives in page blah.php
<?php
// ....
// just basic web site that allows upload of file...
?>
Inside I use system call
if (system("blah.pl arg1") != 0)
{
print "error\n";
}
else
{
print "working on it..you will receive e-mail at completion\n";
}
Works great but it waits until it completes until it prints working on it.
I am aware that I am calling perl script from php not a typo.
How can I just start program execution and let it complete in background.
The blah.pl script handles e-mail notification.
Anyone?
Thanks I appreciate it
From system function documentation:
Note: If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.
Simply redirect the output of your Perl script and PHP should be able to run without having to wait for the script to finish.
system("blah.pl arg1 > /dev/null 2>&1 &");
Can you add an ampersand to spawn the process in the background?
if (system("blah.pl arg1 &") != 0)
You could probably use the popen function
http://www.php.net/manual/en/function.popen.php
Since all the PHP command line functions wait for a result - I recommend that you have a separate page to call the emailer script.
In other words, send a request to the email.php page (or whatever) using cURL or the file wrappers which allows you to close the connection before receiving a result. So the process will look something like this.
page_running.php
|
cURL call to (email.php?arg1=0)
| |
final output email.php
|
calls system("blah.pl arg1")
I have a Python script I recently wrote that I call using the command line with some options. I now want a very thin web interface to call this script locally on my Mac.
I don't want to go through the minor trouble of installing mod_python or mod_wsgi on my Mac, so I was just going to do a system() or popen() from PHP to call the Python script.
Any better ideas?
Depending on what you are doing, system() or popen() may be perfect. Use system() if the Python script has no output, or if you want the Python script's output to go directly to the browser. Use popen() if you want to write data to the Python script's standard input, or read data from the Python script's standard output in php. popen() will only let you read or write, but not both. If you want both, check out proc_open(), but with two way communication between programs you need to be careful to avoid deadlocks, where each program is waiting for the other to do something.
If you want to pass user supplied data to the Python script, then the big thing to be careful about is command injection. If you aren't careful, your user could send you data like "; evilcommand ;" and make your program execute arbitrary commands against your will.
escapeshellarg() and escapeshellcmd() can help with this, but personally I like to remove everything that isn't a known good character, using something like
preg_replace('/[^a-zA-Z0-9]/', '', $str)
The shell_exec() operator will also allow you to run python scripts using similar syntax to above
In a python file called python.py:
hello = "hello"
world = "world"
print hello + " " + world
In a php file called python.php:
$python = shell_exec(python python.py);
echo $python;
You can run a python script via php, and outputs on browser.
Basically you have to call the python script this way:
$command = "python /path/to/python_script.py 2>&1";
$pid = popen( $command,"r");
while( !feof( $pid ) )
{
echo fread($pid, 256);
flush();
ob_flush();
usleep(100000);
}
pclose($pid);
Note: if you run any time.sleep() in you python code, it will not outputs the results on browser.
For full codes working, visit How to execute python script from php and show output on browser
I do this kind of thing all the time for quick-and-dirty scripts. It's quite common to have a CGI or PHP script that just uses system/popen to call some external program.
Just be extra careful if your web server is open to the internet at large. Be sure to sanitize your GET/POST input in this case so as to not allow attackers to run arbitrary commands on your machine.
Your call_python_file.php should look like this:
<?php
$item='Everything is awesome!!';
$tmp = exec("py.py $item");
echo $tmp;
?>
This executes the python script and outputs the result to the browser.
While in your python script the (sys.argv[1:]) variable will bring in all your arguments. To display the argv as a string for wherever your php is pulling from so if you want to do a text area:
import sys
list1 = ' '.join(sys.argv[1:])
def main():
print list1
if __name__ == '__main__':
main()
The above methods seems to be complex. Use my method as a reference.
I have this two files
run.php
mkdir.py
Here, I've created a html page which contains GO button. Whenever you press this button a new folder will be created in directory whose path you have mentioned.
run.php
<html>
<body>
<head>
<title>
run
</title>
</head>
<form method="post">
<input type="submit" value="GO" name="GO">
</form>
</body>
</html>
<?php
if(isset($_POST['GO']))
{
shell_exec("python /var/www/html/lab/mkdir.py");
echo"success";
}
?>
mkdir.py
#!/usr/bin/env python
import os
os.makedirs("thisfolder");
Note that if you are using a virtual environment (as in shared hosting) then you must adjust your path to python, e.g: /home/user/mypython/bin/python ./cgi-bin/test.py
is so easy 😁
You can use [phpy - library for php][1]
php file
<?php
require_once "vendor/autoload.php";
use app\core\App;
$app = new App();
$python = $app->python;
$output = $python->set(your python path)->send(data..)->gen();
var_dump($ouput);
python file:
import include.library.phpy as phpy
print(phpy.get_data(number of data , first = 1 , two =2 ...))
you can see also example in github page
[1]: https://github.com/Raeen123/phpy
If you want to execute your Python script in PHP, it's necessary to do this command in your php script:
exec('your script python.py')