Python to PHP strange error - php

I hope somebody can help me. :)
I am calling a python script from PHP, with the help from phpseclib/ssh2 i ssh into my server and it works fine.
My problem is that if i use "time.sleep(5)" in the loop of my python script i dont get a result back, but if i remove time.sleep(5) and time.sleep(3) it works.
Anybody have an idea why this happen?
If i try the python script i my console everything is picture perfect.!
items = [
'1',
'2',
'3'
]
itemArray = {}
def checker():
for item in items:
time.sleep(5) # If added not working, if removed working, result gets send back
position = 1 # keeps track of the ranking position
for start in range(int(deep)):
time.sleep(3)
results = 'something'
for div in results:
try:
if div.find('i', href=True)['href'].find(something) != -1:
exit_conditon = True
break
else:
position += 1
except:
print "Unexpected error:", sys.exc_info()[0]
raise
if 'exit_conditon' in locals():
if exit_conditon is True:
exit_conditon = False
itemArray.update({value: 1})
break
sys.exit(itemArray)
checker()
Please help.
Update: if i have 3 rows in the items array i need to remove the second time.sleep(5) to get it working, if i have 2 items in my array i only need to remove the first time.sleep(5).

It depends how long your script take time to execute. If your script (php + python) take longer than 30 second with the default config, them php kill it.
Just add set_time_limit(120) at the beginning of your php code
See http://php.net/manual/en/function.set-time-limit.php
And If you are executing the php and python script on the same server you should use exec or shell_exec. It will be faster this way. See php shell_exec() vs exec()

The script is now working as i should do :) Thanks to "neubert" for the answer.
If i set the $ssh->setTimeout() to unlimited, whould i still get a respons if the script halts at some point?

Related

PHP exec() function only runs extremely short Python scripts

I'm having some trouble using the PHP exec() function. Whenever the script I'm attempting to run is short, exec() works just fine. But if the script takes any more than a second or so, it fails. Note, I've attempted run the long script manually on the command line, and it works just fine. It seems as though the PHP interpreter is killing my external script if it takes any longer than a second or so to run. Any thoughts or suggestions? Here is my code:
<?php
$fileName = "foobar.docx";
$argVar = $fileName;
exec("python3 /var/www/html/jan8/alexandrina.py /var/www/html/jan8/$argVar");
echo "$output";
?>
And here is my script:
#!/usr/bin/env python3
import docx
import sys
docxFile = "".join(sys.argv[1:])
# The Three Lines Below Create a New Variable "htmlFile"
# "htmlFile" is the same as "docxFile", except ".docx" is cut off
# and replaced with ".html"
myNumber = len(docxFile) - 5
htmlFile = docxFile[0:myNumber]
htmlFile = htmlFile + '.html'
def generateHTML(filename):
doc = docx.Document(filename)
fullText = []
for para in doc.paragraphs:
fullText.append('<p>')
fullText.append(para.text)
fullText.append('</p>')
fullText.append('\n')
return '\n'.join(fullText)
file = open(htmlFile, "w")
file.write(generateHTML(docxFile))
file.close()
print("end python script")
Additional notes: I've increased the max execution time limits in php.ini, but I don't think that should matter, as the "long script" should only take a few seconds to run. Also, when I refer to the "short script", and the "long script", I'm actually referring to the same script. The difference between the "long script" and the "short script" is just the time to execute as it may vary depending on the size of the file I'm asking the script to process. Anyway... any suggestions would really be appreciated!
Ordinarily, php exec function should block until the command you run has completed. I.e., the PHP script will halt, waiting for the command to finish until continuing with the rest of your script. I was half thinking that your server was experiencing a max_execution_time timeout, but you've clearly stated that even just a couple of seconds is too long and even these fairly short scripts are having trouble.
A couple of solutions occur to me. The simplest one is to alter the python command so that a) any output is routed to a file or output stream and b) the process is run in the background. According to the docs on exec:
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.
I also would like you to make use of the two additional optional parameters for the exec function.
$fileName = "foobar.docx";
$argVar = $fileName;
$cmd = "python3 /var/www/html/jan8/alexandrina.py /var/www/html/jan8/$argVar";
// modify your command to toss output, background the process, and output the process id
$cmd_modified = $cmd . " >/dev/null & echo \$!";
$cmd_output = NULL; // this will be an array of output
$cmd_return_value = NULL; // this will be the return value of the script
exec($cmd_modified, $cmd_output, $cmd_return_value);
echo "exec has completed</br>";
echo "output:<br>" . print_r($cmd_output, TRUE) . "<br>";
echo "return value: " . print_r($cmd_return_value, TRUE);
This may help or may not. If it does not, we still might be able to solve the problem using posix commands.
EDIT: according to crispytx, the long scripts are resulting in a $cmd_return_val of 1 which means an error is happening. Try changing this one line:
$cmd_modified = $cmd . " >/dev/null & echo \$!";
to this
$cmd_modified = $cmd . " & echo \$!";
And let us know what the output of $cmd_output is -- it should at the very least have the process id of the newly spawned process.
Thanks for all the help S. Imp. I had a little trouble debugging using your suggestions because I happened to be using AJAX to call the script. However, I wrote simpler script using your suggestions to try and debug the problem and this is what I found:
Array ( [0] => Traceback (most recent call last): [1] => File "/var/www/html/jan8/alexandrina.py", line 28, in [2] => file.write(generateHTML(docxFile)) [3] => UnicodeEncodeError: 'ascii' codec can't encode character '\u2026' in position 25: ordinal not in range(128) )
So it looks like the problem has to do with ascii encoding! Even though the larger file was just a docx file with the same text as the shorter docx file repeated over and over again for 300 pages. It seems that if a docx file exceeds 1 pages, ascii characters are inserted that aren't present in single page docx files. I have no idea if this post will ever end up helping anyone, but who knows!
[SOLVED]

Echo Exec ("python filepath $variables") Not Working

I have a bit of backend code that is executed like so:
python filepath $inputvariable
This code prints out some data. As you can see in the screenshot below, when I run this code through terminal it works flawlessly, outputting the expected value:
CHI 110^*^Integrated Chinese Level 1 Part 1^*^https://www.amazon.com/Integrated-Chinese-Simplified-Characters-Textbook/dp/0887276385/ref=sr_1_1?ie=UTF8&qid=1466983577&sr=8-1&keywords=integrated+chinese^*^47.49
But I run into issues when I try to run the same code through php:
echo exec ("python /Users/USERNAME/Desktop/Exeter_Bookstore_Project/localserver/cont/Scripts/Python/serverside.py $classToSend");
This code returns a null value. At first I assumed that I wasn't passing variables through correctly, but echo $classToSend; yielded the correct variable. Then I tried having the php execute a hello world python script, but this also worked proving that the issue wasn't in my python interpreter. Then I thought that maybe the python script wasn't forwarding data quickly enough, but the helloworld.py still worked even with a time delay of 3 seconds.
Does anyone have any idea of what I might have done wrong, or do you need more information. Any help will be greatly appreciated.

php exec() and shell_exec()

I currently have a php page that my webserver serves. In order to display all the information I need to display on the page I need output from an external python script. So I have been using the exec() command of php to execute the python script and capture the output in an array of strings as follows:
$somequery = $_GET['query'];
$result = exec("python /var/www/html/query/myscript.py ".somequery."");
//some for loop to loop through entries in result and echo them.
However there are never any entries to be printed, yet when I run the command directly on the console of the server it will output correctly. I've tried echoing out the command on the webpage that I am executing and it's the correct command. The only thing I think it can be is that exec() doesn't stop the rest of the php program from executing before it finishes, leading to the loop i have printing out entries finding that $result is empty.
How can I ensure that exec() finishes executing before the rest of my php script? Are there maybe settings in php.ini that I would need to change? I'm not entirely sure.
EDIT: I've tried running and storing the output of shell_exec("echo hello"); and printing that output, it now prints. However, when running my command that takes a few seconds longer, the program never finishes executing it before going to the next line.
EDIT 2: I found my solution in the following post https://stackoverflow.com/a/6769624 My issue was with with the numpy python package I was using and I simply needed to comment out the line in /usr/lib64/python2.7/ctypes/init.py like the poster did and my script output correctly.
The correct way to get your shell output is like this:
exec("python /var/www/html/query/myscript.py ".somequery."", $result);
var_dump($result); //output should be in here
Give it a try.

PHP exec on another PHP file - How to get my script to wait?

I'm running a continuous PHP loop that executes another PHP file by using exec("php ...");. The plan is for the executed script to run, then sleep for 2 seconds, then start again. However, it seems like my loop is starting a new instance every 2 seconds instead. So long question short, how do I get my first php script to wait until the execution of script nr 2 is complete?
All this is run using the command line. I would also like the echo functions in script nr 2 to show up on the command line.
Any thoughts would help.
Thanks
Exec does not maintain any state information between instances. You could:
Loop in your subscript
OR
You could set some sort of environment variables or that are read at the beginning of the subscript and written at the end.
OR
You could have the subscript read/write to a file in a similar fashion
OR
You could pass in parameters to the subscript who's output is captured
For outputting to the screen, you might play around with the other exec/system calls:
exec
shell_exec
passthru
system
I believe passthru() will work. Another possibility if it doesn't is to call exec(), using the output parameters to capture the output strings from the subscript. Then just echoing that output on return of the subscript.
I also believe that using the output parameters (or capturing the result of the function in a variable) will cause the exec to wait until the command is complete before continuing on.
The problem is, once you excute the script, it will run. Another exec will start another instance like you found out.
What you can do is
Put the sleep inside the executed script. Once it starts running, it will do its own sleep. You can look at setting an execution time limit and maybe ignoring user abort.
You can create a function and let your script call that function. It will then sleep after execution and call the function again.
// maybe set time limit here
Function loop ()
{
Sleep(120);
//you can make a check whether to loop or not.
Loop();
}
Loop();

Shell Script Segmentation Fault

Hi I have a shell script which should run based on the return of php code:
x=1
while [[ "$x" != 5 ]]
do
echo "Welcome $x"
php test.php
x=$?
done
And the php code
echo "Testdfdf test".PHP_EOL;
exit(4);
So I want whenever I get 5 from php to quit the loop.
But I get sometimes:
./myshell: line 7: 20529 Segmentation fault php test.php
Should it loop without problem?
Probably because of this error which affects both Ubuntu and Debian... https://bugs.launchpad.net/ubuntu/+source/php5/+bug/343870
It should and it does, but no clue about why php is ending with a segfault.
your shell while loop will loop forever, as your php script returns 4 to shell, and your while loop checks for !=5. which means the condition is not going to be met. what actually is it you are wanting to do? unless necessary, i would advise to do everything with php (or shell) , but try not to intermingle both.

Categories