Read php var from Python - php

Here is my code, that is supposed to work according to answers to other similar questions, but it does not.
PHP:
<?PHP
$par = $_POST["parameter"];
$importPar=exec("py pyData.py . $par"); //also tried shell_exec()
print ($par);
print($importPar);
?>
Python:
import sys
who = sys.argv[1]
print("This is php var: ",who)
It might have to do something with my cmd because nothing is returned even when I try:
$test=shell_exec('ipconfig');
echo $test;

With minor modifications, your code works just fine on my PHP 5.6.3 setup. The only substantive difference in my example below is that $par gets set locally, and not from a $POST input.
Minor corrections:
1. The . isn't necessary when you're including a $variable inside double quotes. This will actually make python think you want to print . instead of $par, as . is read as sys.argv[1].
2. I'm assuming py is an alias, but I needed to use python in exec() to run properly.
3. You'll get a tuple as print output with your python statement as-is: ('This is php var: ', 'foo')
. Consider using .format() instead, see below.
""" test.py
import sys
who = sys.argv[1]
print('This is php var: {}'.format(who))
"""
<?PHP
$par = "foo";
$importPar=exec("python test.py $par");
print ("$par\n");
print($importPar);
?>
Output:
foo
This is php var: test.py
Process finished with exit code 0

Related

php passthru returns no output

I am trying to call a python script from php. However, I cannot figure out how to return the result to my php script in order to use it there. My php script is as follows:
<?php
$input = 'help';
$output = passthru("/usr/bin/python3.5 /path/test.py '$input'");
echo $output;
?>
whilst my python script 'test.py' is:
import sys
json2 = sys.argv[1]
That's because your python script returns nothing. Just doing:
json2 = sys.argv[1]
Only assigns the value to json2. I suspect you're trying to do something like:
import sys
json2 = sys.argv[1]
print json2
That seems to work just fine:
~ # php -a
Interactive shell
php > $input = 'help';
php > $output = passthru("/usr/bin/python test.py '$input'");
help
Update:
Based on your comment. You're looking for exec() instead:
~ # php -a
Interactive shell
php > $input = 'help';
php > $output = exec("/usr/bin/python test.py '$input'");
php > echo $output;
help
Note that your Python script has to output something. Just assigning a variable is not going to work, since PHP cannot interpret your Python code for you. It can only run the script and do something with the script's output.

Unable to call a python script through PHP

I Have been stuck for a couple of days now. I am attempting to call a simple python script from PHP. For the life of me I cannot figure out what the issue is. I have made the onoff.py script executable with chmod +x.
I can run the script just fine from the command line like this:
pi#raspberrypi:/var/www/html $ python onoff.py
LED on
LED off
My issue is when I try to call the script from PHP. I get nothing.
My Python Script:
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(18,GPIO.OUT)
print "LED on"
GPIO.output(18,GPIO.HIGH)
time.sleep(1)
print "LED off"
GPIO.output(18,GPIO.LOW)
My PHP Script:
<?php
$command = escapeshellcmd('python /var/www/html/onoff.py');
$output = shell_exec($command);
echo $output;
?>
Any help is greatly appreciated!
EDIT:
if I change my onoff.py script to a simple while loop such as:
#!/usr/bin/python
x=1
while (x<10):
print x
x=x+1
the output on the browser is:
1 2 3 4 5 6 7 8 9
I just don't understand why the loop will run but I get no output with the original python code.
EDIT 2:
Ok So I taking a different approach and trying to see where the code fails. I am adding bits of code at a time. Please see the following.
#!/usr/bin/python
import random
import time
import RPi.GPIO as GPIO
randomNumber = random.randint(1, 20)
GPIO.setmode(GPIO.BCM)
#GPIO.setup(18,GPIO.OUT)
print randomNumber
Now when I run the PHP it shows a random number so I know the python script is running. When I un-comment GPIO.setup(18,GPIO.OUT) and run the php I get a blank screen. I have no idea why this would make the script fail.
shell_exec() will only return a string if $command a). Ran OK and assuming b). that it spits its response to STDOUT.
Use exec() and pass it your command, an integer $code and an empty array $response both of which are treated by PHP as arguments by reference.
Run your command thus:
$command = escapeshellcmd('/path/to/python /var/www/html/onoff.py');
$response = array();
$code = 0;
exec($command, $response, $code);
var_dump($code, $response);
die;
You should now see what is actually being given to PHP internally and why the Python script isn't working.
You need to use python before the script, i.e.:
$command = escapeshellcmd('python /var/www/html/onoff.py');
If it doesn't work, python probably ins't on the PATH of the apache user and you may need to use the full path to the python binary, use which to find the full path:
which python
//usr/bin/python
The use that value:
$command = escapeshellcmd('/usr/bin/python /var/www/html/onoff.py');
Note:
Make sure apache user has execute permissions on onoff.py

How to properly call Python 3 script from PHP?

I would like to call a Python 3 script (with arguments) from PHP and process the returned information.
//server.php
arg1 = $_POST['arg1'];
arg2 = $_POST['arg2'];
args = array(arg1,arg2);
//pseudo code - THIS IS WHERE MY QUESTION IS
//$results = call_python3_script_somehow
echo $results
#script.py
import MyProcess
#take in args somehow
args = [arg1,arg2]
result = MyProcess(args)
return result
The problem is this has been asked many times on Stack Overflow, and there are different answers each one:
The execute function (here and here)
$output = array();
exec("python hi.py", $output);
var_dump( $output);
The escape shell function (here)
$command = escapeshellcmd('/usr/custom/test.py');
$output = shell_exec($command);
echo $output;
The shell execute function (here)
// This is the data you want to pass to Python
$data = array('as', 'df', 'gh');
// Execute the python script with the JSON data
$result = shell_exec('python /path/to/myScript.py ' . escapeshellarg(json_encode($data)));
The system function (here)
$mystring = system('python myscript.py myargs', $retval);
All of these answers are accepted and have a decent number of upvotes. Which, if any of these, is the proper way to call a Python script from PHP?
They all do the same thing but have some different output. I would suggest to use the one that best fits your scenario.
I often use shell_exec because it's easier for me on debugging since I all I need to do is just print a string out in <pre> tags. There's one thing that people tend to forget, especially when they are trying to debug stuff. Use: 2>&1 at the end of the script and the args. Taking one of the examples you have above, it would look something like this:
shell_exec('python /path/to/myScript.py ' . escapeshellarg(json_encode($data)) . " 2>&1");
This allows you to view error output as well, which is more than likely what you'll need to figure out why it's working on the command line, but it's not working when you run it from PHP.

PHP variable into Python

I understand there are questions like mine already asked, but I can't figure this out even with the answers in those questions.
PHP:
<?php
$var1 = "hi";
$result = shell_exec('TestingStuff.py'.$var1);
?>
Python:
import sys
print(sys.argv[1])
Error received when running in Python:
IndexError: list index out of range
Both scripts are in the same folder.
Could someone please provide an answer with the code changes?
Error
If the Python script runs with no arguments at all, then that sys.argv[1] index is out of range.
Scripts
ExecPython.php
<?php
$var1 = "hi";
$result = shell_exec('TestingStuff.py ' . $var1);
echo "<pre>$result</pre>";
TestingStuff.py
import sys
if len(sys.argv) > 1:
print(sys.argv[1])
Demo
Explanation
We will start with the Python script. The goal is, that the script prints the first argument passed to it - without running into the "IndexError: list index out of range" error.
python TestingStuff.py 123 we want the output 123.
In Python the arguments passed to the script reside in sys.argv. It's a list. sys.argv[0] is always the script name itself (here TestingStuff.py). Using the example from above sys.argv[1] is now 123.
Handling the edge cases: "no argument" given.
python TestingStuff.py
This will result in an "IndexError: list index out of range" error, because you are trying to access a list element, which is not there. sys.argv[0] is the script name and sys.argv[1] is not set, but you are trying to print it and BAM goes the error. To avoid the error and only print the first argument, we need to make sure, that the list sys.argv contains more than one element (more than the script name). That's why i've added if len(sys.argv) > 1:.
That means: print the first argument only, if the list has more than 1 argument.
Now we can test the Python script standalone - with and without arguments.
And switch over to the PHP script.
The goal is to execute the Python script from PHP.
PHP provides several ways to execute a script, there are for instance exec(), passthru(), shell_exec(), system(). Here we are using shell_exec(). shell_exec() returns the output of the script or command we run with it.
In other words: if you run $result = shell_exec('php -v');, you'll get the PHP version lines in $result.
Here we are executing the Python script TestingStuff.py and add an argument, which is $var1. It's a string and added via concatenation to the string given to shell_exec(). The $result is echoed. I wrapped pre-tags around it, because i thought this is executed in the web/browser context. If you are using the scripts only on the CLI, you might drop the pre-tags.
Execution flow
the PHP script is executed
shell_exec() executes the Python script
shell_exec() returns the output of the Python script as $result
$result is printed by PHP via echo

Catch Python script output in PHP and avoid double output

I am executing a Python script in PHP using system(). For me to get the result of my Python script, I use print command and catch the result in PHP. Here's my code:
Python (test.py)
import sys
name = sys.argv[1]
print 'Your name is ' + name
PHP
$result = system('python test.py John');
echo $result;
/* PHP Output */
Your name is John
Your name is John
As you can see, the output is doubled. The first one was generated by the Python script itself, the second one was because of echo command. Is there a way on how to avoid this doubled output? I just wanted to catch the result and will use it somewhere on my PHP script.
**NOTE: Just wondering if there is another way on how to pass Python script output to PHP a variable. My only intention here is to put the output on a PHP variable.
You can try with exec function. It also performs a command execution but, at diference fo system, doesn't output the content to standard output. The only drawback is that the return is an array of every line in the stadard output (not a string, like system. You can also try with proc_open, that allows you redirect the output to an arbitrary pipe.

Categories