Call Python from PHP and Get Return Code

Call Python From PHP And Get Return Code

In PHP, you can execute a command and obtain the return code using exec.

The manual for exec says the third parameter is a variable in which the return code will be stored, for example

exec('python blibble.py', $output, $ret_code);

$ret_code will be the shell return code, and $output is an array of the lines of text printed to std. output.

This does appear to be an appropriate use for a return code from what you described, i.e. 0 indicating success, and >0 being codes for various types of errors.

get python to print/return value on your website with php

shell_exec returns the output of your script. so use

$cmd = escapeshellcmd('sudo python3 piUno.py'); 
$output = shell_exec($cmd);
echo $output;

should work! let me know if it doesn't

edit: oh hey! your question got me looking at doc to check myself and exec actually returns the last line of output if you need only the last output.

$output = exec('sudo python3 piUno.py');
echo $output;

or, you can set a second parameter to exec() to store all output lines in an array (1 entry per line) as this

$output = array();
exec('sudo python3 piUno.py',$output);
var_dump($output);

aight! this was fun!

PHP show return from python script

You need to pass $result as a param into exec() otherwise you only get the last statement.

exec('python list.py', $result);
print_r($result);

This will get an array of output, $result[0] will contain stop and $result[sizeof($result)-1] will contain stop and everything in between will contain the rest of your program output.

How to execute a Python program in PHP and use the return value inside HTML p/?

Easy and quick way

To wrap your $output variable into paragraph tags you could do this.

echo "<p>$output</p>";

More modular and reusable

If you want to include this in your template, you could put your php code into a function and then call it from your template. But here, don't echo the value, return it instead.

<?php
function getData()
{
$command = escapeshellcmd('main.py');
$output = shell_exec($command);
return $output;
}
?>

And then call your function from your template.

<p><?php echo getData(); ?></p>

Running PHP code without waiting for Python return value

Introduction

There's many things wrong with your code, and the method which you are using to go about doing this. I will try to answer it as simply as possible, but do bear in mind that this is not an easy problem - it will probably take some explanation.


The Problems With Your Code

Firstly, why does your existing solution not work? Some of the things that I notice right away are:

  • A while(true) loop is infinite. Since you never break out of it, this code will never finish executing. You probably intended to use $timeVar as the conditional for your while loop and change it within your code, but never did.

  • In every loop, if less than 300 seconds have gone past, you try to read the output of the Python script again, by executing it again. What you have forgotten here is that exec() is a blocking function - that means that nothing after it will execute until it has finished - so you'll just be waiting for the entire execution of the script here - nothing has really changed by putting it in the loop.

Of course, these are understandable mistakes. This is a hard problem.


The exec() Function

A lot of this problem seems to boil down to exec(), the function used to execute command-line statements, waiting for the statement to finish before any other code is executed. The reason for this is due to how commands actually work - if they need to print out errors or output, they need to print to stderr and stdout respectively. In PHP, exec() acts as stderr and stdout, and thus commands need to be able to send output there. This means that PHP can't move on until the command has finished.

If you were using a *nix system, this would be a lot easier. However, on Windows, we will have to move away from using exec() and instead, use two different functions: popen() and pclose().

Firstly, we need to make the command run in the background, though. This is a simple enough task: at the beginning of your command, where you have written start, we will instead write start \b (start in background).

But wait! How are we going to get the result of the command, if it always runs in the background? This is where the redirection operator, >>, comes in. It sends all output from a shell function into a file instead. Because we used two > characters, it will overwrite any file that already exists there. This will become important later on.

So, make a folder in your test directory (where the PHP and Python scripts are contained), and call it output. Then, we'll generate a name for the file in PHP, so that multiple people can use your website at once without getting each-others output. We can just use the time() function for this - it is unlikely that they would both do it at the exact same second. Now you should be able to send output to a file in the output directory, which will be named after the current time() value.

Now for the hard bit: executing it. popen() runs the command. Its first parameter is the command, the second is its mode. It returns a resource pointer. You can read about this on the PHP manual, linked below. All we need to know is that with a mode of "r", it will also return a resource if it errors (containing any shell error messages), so it runs the command and always returns a pointer that we need to close.

Thus:

$filename = time().".txt";
pclose(popen("start \b C:/Python26/python C:/xampp/htdocs/test/timeout.py >> \"C:/xampp/htdocs/test/output/$filename\"", "r"));

should run our command in the background.

Further reading on this topic:

  • php exec command (or similar) to not wait for result
  • How To Redirect Command Prompt Output to a File
  • exec on the PHP manual
  • popen on the PHP manual

Finishing secondpg.php

Now, we have your Python script running in the background. Our PHP file can end and display a page to the user, and the Python will still be running on the server. But how will we ever get the output?

Firstly, we'll need to remember the filename - storing it in a session cookie should work quite nicely. At the very top of secondpg.php, we'll need to add the code session_start(), so that we can use session cookies. Then, we'll store the filename in a cookie by setting it using the session superglobal: $_SESSION["filename"] = $filename;.

Another thing we need to do is ensure that the file exists, so that we can check if it is empty later (>> will overwrite it with the output of the Python script, but only after the script is finished). We can create the file using file_put_contents().

We'll also need to include a JavaScript file (which we have not written yet). Thus, here is secondpg.php:

<?php
session_start(); //Allows us to use sessions

$time = time(); //Creates a filename using the current time past the epoc as a unique identifier

file_put_contents("output/$time",""); //Ensure that the file exists, and is empty

$_SESSION["time"] = $time; //Sets the filename in a session cookie, so we can use it later

pclose(popen("start \b C:/Python26/python C:/xampp/htdocs/test/timeout.py >> \"C:/xampp/htdocs/test/output/$time.txt\"", "r")); //Runs our Python script
?>
<script src="check.js"></script>

Further reading:

  • PHP sessions

Getting The Output

Now, you need to write a new PHP file. Call it get_output.php. The code is pretty basic:

<?php
session_start(); //Allows us to use sessions

if (time()-$_SESSION["time"]>300) { //If the file was made more than 300 seconds (five minutes ago) we just echo timeout
echo "Timeout";
}
else {
echo file_get_contents("output/".$_SESSION["time"].".txt"); //Echo out the contents of the file. Pulls the filename out of our session cookie.
}
?>

Hopefully that file is pretty self-explanatory: it simply echos out the contents of our output file.

Now, we need to write a JavaScript file. This will run on the users computer, and every five seconds, will run the PHP file we just wrote, so that we can check if the file has contents. It will write the contents to the body of the page.

Call this file check.js:

function do_check() {
var http = new XMLHttpRequest(); //Open a request to another page
http.onreadystatechange = function() {
if (http.readyState==4&&http.status==200) { //If we have loaded the page successfully
document.body.innerHTML = http.responseText; //Set the body content to be the response text
}
}
http.open("GET","get_output.php",true); //Request the file
http.send(); //Send the request
}

setInterval("do_check()", 5000); //Call the function every five seconds.

Further reading:

  • JavaScript XMLHttpRequest

Conclusion

That should be all that you need. Every five seconds the page content will be changed to the contents of the file, and you can check this by changing the file yourself - the page should update to show the change.

Running Python script in PHP: capture all outputs

Try with shell_exec - Execute command via shell and return the complete output as a string

escapeshellcmd() escapes any characters in a string that might be used
to trick a shell command into executing arbitrary commands.

Name your file like- python_script.py and follow the given script-

$command = escapeshellcmd('python_script.py');
$output = shell_exec($command);
echo $output;

Ref# running-a-python-script-from-php



Related Topics



Leave a reply



Submit